Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing django.contrib.auth.urls does not play well with existing admin templates

I've been trying to follow documentation on using builtin Django templates to login/logout nonstaff users on a Django (1.9) site. In particular, I modified the urlconf by adding

url('^', include('django.contrib.auth.urls'))

which brings in /login and /logout endpoints and views with default template names preprogrammed.

The default template names for login and logout are registration/login.html and registration/logged_out.html. The first one doesn't exist anywhere, so I assumed I should create a templates/registration/ and create the login template, which I did. I thought the same thing should work for the logout, except it doesn't.

What actually happens is that the template resolves to django.contrib.admin.templates.registration.logged_out.html. This is pretty but stinks because the login link points to the admin login, which no nonstaff user will be able to use.

I really wish I could use the urlconf above, use the default template names, but write my own templates. Isn't this possible? The alternative seems to be repeating a bunch of stuff and that isn't very Pythonic.

I imagine it might involve modification of the TEMPLATES setting, or changing the orders of something else in the settings.

Whatever the solution is, I hope it does not interfere with the proper resolution of the admin templates (i.e. it would be bad if those started using my new templates.)


Requested details:

I created a login.html in (appname)/templates/registration/, and it works just fine when visiting the login url.

I created a logged_out.html in (appname)/templates/registration/ also, but discovered that when visiting the logout url, I got the admin site logged_out template (the one that says "Thanks for spending some quality time with the Web site today."

My templates setting:

TEMPLATES = [
    {
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
         'DIRS': [],
         'APP_DIRS': True,
         'OPTIONS': {
             'debug': True,
             'context_processors': [
                 'django.template.context_processors.debug',
                 'django.template.context_processors.request',
                 'django.contrib.auth.context_processors.auth',
                 'django.contrib.messages.context_processors.messages',
             ],
         },
    },
]

INSTALLED_APPS = (
    'django.contrib.admin',
    'app',
    'django.contrib.auth',
    'django.contrib.contenttypes', 
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles'
)

Project structure (omitting what I guess is nonessential, and using some generic names.)

project/
    app/
        templates/
            app/
            registration/
                login.html
                logged_out.html
        models.py
        views.py
        admin.py
    gettingstarted/
        static/
        settings.py
        urls.py

The structure may look a bit weird since it was adapted starting from the Heroku "Getting started with python" app.

Update

I finally struck upon the right search terms in the Django bug tracker and found that is a known issue. Disappointingly it's already three years old with no comment in the past two years. I guess I will just have to bite the bullet and define my own urls that use templates on a different path.

like image 788
rschwieb Avatar asked Oct 26 '25 15:10

rschwieb


1 Answers

Django's template lookup is done top down by the order of INSTALLED_APPS. Meaning that if you want to override a template, the overriding template app should be listed above the overriden one in the admin.

In this case, project.app should be placed above django.contrib.admin so when creating /registration/logout.html it'll be loaded before the admin template.

In general, the recommended order of installed apps is: project -> 3rd party apps -> django builtins. It also affects static files finders.


Because of a bug in Django, overriding the registration/logged_out.html template overrides the admin "logged_out" template as well.

You can include the logout view specifically and specify a different "logged out" template or next_page (the view where it redirects after logout):

from django.contrib.auth import views as auth_views

urlpatterns = [
    url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
    url('^', include('django.contrib.auth.urls')),
]

This will redirect to / after logout. It can also be a named url.

Or to change the logged_out template location use:

url(r'^logout/$', auth_views.logout, {'template_name': 'logged_out.html'}, name='logout'),

And then create logged_out.html in project/app/templates/.

I would use the first option if you want to redirect the user back to the home page after logout, and the 2nd if you want to display a "logged out" message.

like image 160
yprez Avatar answered Oct 29 '25 07:10

yprez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!