title: django.urls.reverse_lazy Example Code
category: page
slug: django-urls-reverse-lazy-examples
sortorder: 500013630
toc: False
sidebartitle: django.urls reverse_lazy
meta: Python code examples for the reverse_lazy function within the django.urls module of the Django project. 


The [reverse_lazy](https://github.com/django/django/blob/master/django/urls/base.py)
function is contained with the 
[django.urls](https://github.com/django/django/tree/master/django/urls) 
module within the [Django project](/django.html) code base. This function is
actually defined in `base.py` of the `django.urls` directory but it is
typically imported directly from `django.urls`, without `base` in the
import module path.

`reverse_lazy` is used for resolving Django URL names into URL paths.
The resolution is not seen by the end user client as all of this
work occurs within the Django application code and framework code.


## Example 1 from dccnsys
[dccnsys](https://github.com/dccnconf/dccnsys) is a conference registration
system built with [Django](/django.html). The code is open source under the
[MIT license](https://github.com/dccnconf/dccnsys/blob/master/LICENSE).

[**dccnsys / wwwdccn / wwwdccn / settings.py**](https://github.com/dccnconf/dccnsys/blob/master/wwwdccn/wwwdccn/settings.py)

```python
"""
Django settings for wwwdccn project.

Generated by 'django-admin startproject' using Django 2.1.7.

For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""

import os
~~from django.urls import reverse_lazy


def check_bool_env_var(name):
    return name in os.environ and os.environ[name] in {'y', 'yes', 
                                                       'true', 'on'}


# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

REMOTE_DEPLOY = os.environ.get('DJANGO_REMOTE', False)

~~LOGIN_URL = reverse_lazy('login')
~~LOGIN_REDIRECT_URL = reverse_lazy('home')
~~LOGOUT_REDIRECT_URL = reverse_lazy('home')


## ... source file continues without further reverse_lazy examples ...
```


## Example 2 from django-allauth
[django-allauth](https://github.com/pennersr/django-allauth)
([project website](https://www.intenct.nl/projects/django-allauth/)) is a
[Django](/django.html) library for easily adding local and social authentication
flows to Django projects. It is open source under the
[MIT License](https://github.com/pennersr/django-allauth/blob/master/LICENSE).
         

[**django-allauth / allauth / socialaccount / views.py**](https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/views.py)

```python
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.sites.shortcuts import get_current_site
from django.http import HttpResponseRedirect
~~from django.urls import reverse, reverse_lazy
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView

from ..account import app_settings as account_settings
from ..account.adapter import get_adapter as get_account_adapter
from ..account.views import (
    AjaxCapableProcessFormViewMixin,
    CloseableSignupMixin,
    RedirectAuthenticatedUserMixin,
)
from ..utils import get_form_class
from . import app_settings, helpers
from .adapter import get_adapter
from .forms import DisconnectForm, SignupForm
from .models import SocialAccount, SocialLogin


class SignupView(RedirectAuthenticatedUserMixin, CloseableSignupMixin,
                 AjaxCapableProcessFormViewMixin, FormView):
    form_class = SignupForm
    template_name = (
        'socialaccount/signup.' + account_settings.TEMPLATE_EXTENSION)

    def get_form_class(self):
        return get_form_class(app_settings.FORMS,
                              'signup',
                              self.form_class)

    def dispatch(self, request, *args, **kwargs):
        self.sociallogin = None
        data = request.session.get('socialaccount_sociallogin')
        if data:
            self.sociallogin = SocialLogin.deserialize(data)
        if not self.sociallogin:
            return HttpResponseRedirect(reverse('account_login'))
        return super(SignupView, self).dispatch(request, 
                                                *args, **kwargs)

    def is_open(self):
        return get_adapter(self.request).is_open_for_signup(
            self.request,
            self.sociallogin)

    def get_form_kwargs(self):
        ret = super(SignupView, self).get_form_kwargs()
        ret['sociallogin'] = self.sociallogin
        return ret

    def form_valid(self, form):
        self.request.session.pop('socialaccount_sociallogin', None)
        form.save(self.request)
        return helpers.complete_social_signup(self.request,
                                              self.sociallogin)

    def get_context_data(self, **kwargs):
        ret = super(SignupView, self).get_context_data(**kwargs)
        ret.update(dict(site=get_current_site(self.request),
                        account=self.sociallogin.account))
        return ret

    def get_authenticated_redirect_url(self):
        return reverse(connections)


signup = SignupView.as_view()


class LoginCancelledView(TemplateView):
    template_name = (
        "socialaccount/login_cancelled." + \
        account_settings.TEMPLATE_EXTENSION)


login_cancelled = LoginCancelledView.as_view()


class LoginErrorView(TemplateView):
    template_name = (
        "socialaccount/authentication_error." +
        account_settings.TEMPLATE_EXTENSION)


login_error = LoginErrorView.as_view()


class ConnectionsView(AjaxCapableProcessFormViewMixin, FormView):
    template_name = (
        "socialaccount/connections." +
        account_settings.TEMPLATE_EXTENSION)
    form_class = DisconnectForm
~~    success_url = reverse_lazy("socialaccount_connections")

    def get_form_class(self):
        return get_form_class(app_settings.FORMS,
                              'disconnect',
                              self.form_class)

    def get_form_kwargs(self):
        kwargs = super(ConnectionsView, self).get_form_kwargs()
        kwargs["request"] = self.request
        return kwargs

    def form_valid(self, form):
        get_account_adapter().add_message(self.request,
                                          messages.INFO,
                                          'socialaccount/messages/'
                                          'account_disconnected.txt')
        form.save()
        return super(ConnectionsView, self).form_valid(form)

    def get_ajax_data(self):
        account_data = []
        for account in \
            SocialAccount.objects.filter(user=self.request.user):
            provider_account = account.get_provider_account()
            account_data.append({
                'id': account.pk,
                'provider': account.provider,
                'name': provider_account.to_str()
            })
        return {
            'socialaccounts': account_data
        }


connections = login_required(ConnectionsView.as_view())
```


## Example 3 from django-angular
[django-angular](https://github.com/jrief/django-angular)
([project examples website](https://django-angular.awesto.com/classic_form/))
is a library with helper code to make it easier to use
[Angular](/angular.html) as the front-end to [Django](/django.html) projects.
The code for django-angular is
[open source under the MIT license](https://github.com/jrief/django-angular/blob/master/LICENSE.txt).

[**django-angular / djng / forms / fields.py**](https://github.com/jrief/django-angular/blob/master/djng/forms/fields.py)

```python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import re
import mimetypes

from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core import signing
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.core.files.storage import default_storage
from django.core.files.uploadedfile import (InMemoryUploadedFile, 
                                            TemporaryUploadedFile)
~~from django.urls import reverse_lazy
from django.forms import fields, models as model_fields, widgets
from django.utils.html import format_html
from django.utils.module_loading import import_string
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _, ungettext_lazy

from djng import app_settings
from .widgets import DropFileWidget, DropImageWidget


## ... source file abbreviated here to get to the example faster ...


class FileField(FileFieldMixin, fields.FileField):
    storage = app_settings.upload_storage
    signer = signing.Signer()

    def __init__(self, *args, **kwargs):
        accept = kwargs.pop('accept', '*/*')
~~        fileupload_url = kwargs.pop('fileupload_url', 
~~                         reverse_lazy('fileupload'))
        area_label = kwargs.pop('area_label', 
                                _("Drop file here or click to upload"))
        attrs = {
            'accept': accept,
            'ngf-pattern': accept,
        }
        kwargs.update(widget=DropFileWidget(area_label, 
                                            fileupload_url, 
                                            attrs=attrs))
        super(FileField, self).__init__(*args, **kwargs)

    @classmethod
    def preview(cls, file_obj):
        available_name = cls.storage.get_available_name(file_obj.name)
        temp_name = cls.storage.save(available_name, file_obj)
        extension = mimetypes.guess_extension(file_obj.content_type)
        if extension:
            extension = extension[1:]
        else:
            extension = '_blank'
        icon_url = staticfiles_storage.url('djng/icons/{}.png'.\
                                           format(extension))
        return {
            'url': 'url({})'.format(icon_url),
            'temp_name': cls.signer.sign(temp_name),
            'file_name': file_obj.name,
            'file_size': file_obj.size,
            'charset': file_obj.charset,
            'content_type': file_obj.content_type,
            'content_type_extra': file_obj.content_type_extra,
        }


class ImageField(FileFieldMixin, fields.ImageField):
    storage = app_settings.upload_storage
    signer = signing.Signer()

    def __init__(self, *args, **kwargs):
        if 'easy_thumbnails' not in settings.INSTALLED_APPS:
            raise ImproperlyConfigured("'djng.forms.fields.ImageField' "
                                       "requires 'easy-thubnails' to "
                                       "be installed")
        accept = kwargs.pop('accept', 'image/*')
~~        fileupload_url = kwargs.pop('fileupload_url', 
~~            reverse_lazy('fileupload'))
        area_label = kwargs.pop('area_label', 
                                _("Drop image here or "
                                  "click to upload"))
        attrs = {
            'accept': accept,
            'ngf-pattern': accept,
        }
        kwargs.update(widget=DropImageWidget(area_label, 
                                             fileupload_url, 
                                             attrs=attrs))
        super(ImageField, self).__init__(*args, **kwargs)

    def remove_current(self, image_name):
        from easy_thumbnails.models import Source, Thumbnail

        try:
            source = Source.objects.get(name=image_name)
            for thumb in Thumbnail.objects.filter(source=source):
                default_storage.delete(thumb.name)
                thumb.delete()
            source.delete()
        except Source.DoesNotExist:
            pass
        super(ImageField, self).remove_current(image_name)

    @classmethod
    def preview(cls, file_obj):
        from easy_thumbnails.files import get_thumbnailer
        from easy_thumbnails.templatetags.thumbnail import data_uri

        available_name = cls.storage.get_available_name(file_obj.name)
        temp_name = cls.storage.save(available_name, file_obj)
        thumbnailer = get_thumbnailer(cls.storage.path(temp_name), 
                                      relative_name=available_name)
        thumbnail = thumbnailer.generate_thumbnail(app_settings.\
                                                   THUMBNAIL_OPTIONS)
        return {
            'url': 'url({})'.format(data_uri(thumbnail)),
            'temp_name': cls.signer.sign(temp_name),
            'file_name': file_obj.name,
            'file_size': file_obj.size,
            'charset': file_obj.charset,
            'content_type': file_obj.content_type,
            'content_type_extra': file_obj.content_type_extra,
        }
```


## Example 4 from django-cms
[django-cms](https://github.com/divio/django-cms)
([project website](https://www.django-cms.org/en/)) is a Python-based
content management system (CMS) [library](https://pypi.org/project/django-cms/)
for use with Django web apps that is open sourced under the
[BSD 3-Clause "New"](https://github.com/divio/django-cms/blob/develop/LICENSE)
license.

[**django-cms / cms / forms / widgets.py**](https://github.com/divio/django-cms/blob/develop/cms/forms/widgets.py)

```python
# -*- coding: utf-8 -*-
from django.contrib.auth import get_permission_codename
from django.contrib.sites.models import Site
from django.forms.widgets import MultiWidget, Select, TextInput
~~from django.urls import NoReverseMatch, reverse_lazy
from django.utils.encoding import force_text
from django.utils.html import escape, escapejs
from django.utils.safestring import mark_safe

from cms.utils.urlutils import admin_reverse, static_with_version
from cms.forms.utils import get_site_choices, get_page_choices
from cms.models import Page, PageUser


class PageSelectWidget(MultiWidget):
    """A widget that allows selecting a page by first selecting 
    a site and then a page on that site in a two step process.
    """
    template_name = 'cms/widgets/pageselectwidget.html'

    class Media:
        js = (
            static_with_version('cms/js/dist/bundle.forms.pageselectwidget.min.js'),
        )

    def __init__(self, site_choices=None, page_choices=None, attrs=None):
        if attrs is not None:
            self.attrs = attrs.copy()
        else:
            self.attrs = {}
        self.choices = []
        super(PageSelectWidget, self).__init__((Select, Select, Select), attrs)

    def decompress(self, value):
        """
        receives a page_id in value and returns the site_id and page_id
        of that page or the current site_id and None if no page_id is given.
        """
        if value:
            page = Page.objects.select_related('node').get(pk=value)
            return [page.node.site_id, page.pk, page.pk]
        site = Site.objects.get_current()
        return [site.pk,None,None]

    def _has_changed(self, initial, data):
        # THIS IS A COPY OF django.forms.widgets.Widget._has_changed()
        # (except for the first if statement)

        """
        Return True if data differs from initial.
        """
        # For purposes of seeing whether something has changed, None is
        # the same as an empty string, if the data or inital value we get
        # is None, replace it w/ u''.
        if data is None or (len(data)>=2 and data[1] in [None,'']):
            data_value = u''
        else:
            data_value = data
        if initial is None:
            initial_value = u''
        else:
            initial_value = initial
        if force_text(initial_value) != force_text(data_value):
            return True
        return False

    def _build_widgets(self):
        site_choices = get_site_choices()
        page_choices = get_page_choices()
        self.site_choices = site_choices
        self.choices = page_choices
        self.widgets = (Select(choices=site_choices ),
                   Select(choices=[('', '----')]),
                   Select(choices=self.choices, attrs={'style': "display:none;"} ),
        )

    def _build_script(self, name, value, attrs={}):
        return r"""<script type="text/javascript">
                var CMS = window.CMS || {};

                CMS.Widgets = CMS.Widgets || {};
                CMS.Widgets._pageSelectWidgets = CMS.Widgets._pageSelectWidgets || [];
                CMS.Widgets._pageSelectWidgets.push({
                    name: '%(name)s'
                });
            </script>""" % {
                'name': name
            }

    def get_context(self, name, value, attrs):
        self._build_widgets()
        context = super(PageSelectWidget, self).\
                        get_context(name, value, attrs)
        context['widget']['script_init'] = \
            self._build_script(name, value, context['widget']['attrs'])
        return context

    def format_output(self, rendered_widgets):
        return u' '.join(rendered_widgets)


class PageSmartLinkWidget(TextInput):
    template_name = 'cms/widgets/pagesmartlinkwidget.html'

    class Media:
        css = {
            'all': (
                'cms/js/select2/select2.css',
                'cms/js/select2/select2-bootstrap.css',
            )
        }
        js = (
            static_with_version('cms/js/dist/bundle.forms.'
                                'pagesmartlinkwidget.min.js'),
        )

    def __init__(self, attrs=None, ajax_view=None):
        super(PageSmartLinkWidget, self).__init__(attrs)
        self.ajax_url = self.get_ajax_url(ajax_view=ajax_view)

    def get_ajax_url(self, ajax_view):
        try:
~~            return reverse_lazy(ajax_view)
        except NoReverseMatch:
            raise Exception(
                'You should provide an ajax_view argument '
                'that can be reversed to the PageSmartLinkWidget'
            )

## ... source file continues without further reverse_lazy examples ...
```


## Example 5 from django-oscar
[django-oscar](https://github.com/django-oscar/django-oscar/)
([project website](http://oscarcommerce.com/))
is a framework for building e-commerce sites on top of
[Django](/django.html). The code for the project is available open
source under a
[custom license written by Tangent Communications PLC](https://github.com/django-oscar/django-oscar/blob/master/LICENSE).

[**django-oscar / src / oscar / config.py**](https://github.com/django-oscar/django-oscar/blob/master/src/oscar/config.py)

```python
# flake8: noqa, because URL syntax is more readable with long lines

from django.apps import apps
from django.conf import settings
from django.conf.urls import url
~~from django.urls import reverse_lazy
from django.views.generic.base import RedirectView

from oscar.core.application import OscarConfig
from oscar.core.loading import get_class


class Shop(OscarConfig):
    name = 'oscar'

    def ready(self):
        from django.contrib.auth.forms import SetPasswordForm

        self.catalogue_app = apps.get_app_config('catalogue')
        self.customer_app = apps.get_app_config('customer')
        self.basket_app = apps.get_app_config('basket')
        self.checkout_app = apps.get_app_config('checkout')
        self.search_app = apps.get_app_config('search')
        self.dashboard_app = apps.get_app_config('dashboard')
        self.offer_app = apps.get_app_config('offer')

        self.password_reset_form = get_class('customer.forms', 'PasswordResetForm')
        self.set_password_form = SetPasswordForm

    def get_urls(self):
        from django.contrib.auth import views as auth_views

        from oscar.views.decorators import login_forbidden

        urls = [
~~            url(r'^$', RedirectView.as_view(url=reverse_lazy('catalogue:index')), name='home'),
            url(r'^catalogue/', self.catalogue_app.urls),
            url(r'^basket/', self.basket_app.urls),
            url(r'^checkout/', self.checkout_app.urls),
            url(r'^accounts/', self.customer_app.urls),
            url(r'^search/', self.search_app.urls),
            url(r'^dashboard/', self.dashboard_app.urls),
            url(r'^offers/', self.offer_app.urls),

            # Password reset - as we're using Django's default view functions,
            # we can't namespace these urls as that prevents
            # the reverse function from working.
~~            url(r'^password-reset/$',
~~                login_forbidden(
~~                    auth_views.PasswordResetView.as_view(
~~                        form_class=self.password_reset_form,
~~                        success_url=reverse_lazy('password-reset-done'),
~~                        template_name='oscar/registration/password_reset_form.html'
~~                    )
~~                ),
~~                name='password-reset'),
            url(r'^password-reset/done/$',
                login_forbidden(auth_views.PasswordResetDoneView.as_view(
                    template_name='oscar/registration/password_reset_done.html'
                )),
                name='password-reset-done'),
~~            url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
~~                login_forbidden(
~~                    auth_views.PasswordResetConfirmView.as_view(
~~                        form_class=self.set_password_form,
~~                        success_url=reverse_lazy('password-reset-complete'),
~~                        template_name='oscar/registration/password_reset_confirm.html'
~~                    )
~~                ),
~~                name='password-reset-confirm'),
            url(r'^password-reset/complete/$',
                login_forbidden(auth_views.PasswordResetCompleteView.as_view(
                    template_name='oscar/registration/password_reset_complete.html'
                )),
                name='password-reset-complete'),
        ]
        return urls
```


