14

Is there a ready way to use the Django admin page without any form of authentication? I know I can use this method, but that was for Django 1.3. Are there any changes that would let me do this more easily in Django 1.6?

My main motivation for this is that I want to have as few database tables as possible, and I am using this only locally, so there is no need for any sort of authentication (I'm only ever running the server on localhost anyways).

Community
  • 1
  • 1
pseudonym117
  • 799
  • 1
  • 5
  • 22

6 Answers6

17

The accepted answer is already super simple however after messing around with this I found that in recent versions of Django (since admin.site.has_permission became a thing... >= 1.8?) you can do it without middleware.

In your project's urls.py:

from django.contrib import admin

class AccessUser:
    has_module_perms = has_perm = __getattr__ = lambda s,*a,**kw: True

admin.site.has_permission = lambda r: setattr(r, 'user', AccessUser()) or True

# Register the admin views or call admin.autodiscover()

urlpatterns = [
    # Your url configs then...
    url(r'^admin/', admin.site.urls),
]

If you have AccessUser extend User you can leave out the __getattr__ portion which is a hacky way to return something when user.pk or similar is called.

roblinton
  • 190
  • 1
  • 5
  • 2
    Note that when one tries to change something using this construction, django admin complains: `insert or update on table "django_admin_log" violates foreign key constraint "django_admin_log_user_id_c564eba6_fk_auth_user_id" DETAIL: Key (user_id)=(1) is not present in table "auth_user".`, so you do need to have a user if you need that functionality. – Jieter Nov 14 '17 at 10:12
  • This is what i was looking for past one week. I didn't need login page since my application is internally used. – Harshita Sep 25 '19 at 10:24
  • Here a ticket with solution for problem mentioned by @Jieter: https://stackoverflow.com/questions/58736821/prevent-django-admin-changes-from-creating-a-logentry – Mateusz Sep 25 '22 at 19:14
13

Create a module auto_auth.py:

from django.contrib.auth.models import User
from django.utils.deprecation import MiddlewareMixin

class AutoAuthMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = User.objects.filter()[0]

Edit MIDDLEWARE in your settings.py:

  • Remove 'django.contrib.auth.middleware.AuthenticationMiddleware'
  • Add 'auto_auth.AutoAuthMiddleware'

You can change User.objects.filter()[0] to something else if you want a particular user.


In response to your comment: yes. To run the Django admin without users at all, try this:

class User:
    is_superuser = True
    is_active = True
    is_staff = True
    id = 1

def return_true(*args, **kwargs):
    return True
User.has_module_perms = return_true
User.has_perm = return_true

class AutoAuthMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = User()

And remove 'django.contrib.auth' from INSTALLED_APPS

But if you use any apps that depend on the auth app, you're going to have a bad time.

Jamie Cockburn
  • 7,379
  • 1
  • 24
  • 37
5

The accepted answer adapted for Django version >= 1.10

/[yourapp]/middleware.py:

from django.contrib.auth.models import User

class AuthenticationMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request.user = User.objects.filter()[0]
        return self.get_response(request)  

In [yourproject]/settings.py for the MIDDLEWARE list:

  • Comment or remove: 'django.contrib.auth.middleware.AuthenticationMiddleware',
  • Append: '[yourapp].middleware.AuthenticationMiddleware',

Probably obvious to most people but note that the solution still requires one user to exist. Create one manually python manage.py createsuperuser or automatically with a script:

hellbe
  • 301
  • 2
  • 10
4

Another Option allows access from anyone: get the first user to bypass authentication

# app/admin.py
from django.contrib.auth.models import User
anonymous_user = User.objects.all().first()
admin.site.has_permission = lambda r: setattr(r, 'user', anonymous_user) or True
HoangYell
  • 4,100
  • 37
  • 31
0

For the newer versions of django >=2.1 you need to do something like this:

auto_auth.py

class User:
    is_superuser = True
    is_active = True
    is_staff = True
    id = 1
    pk = 1


User.has_module_perms = True
User.has_perm = True


class Middleware(object):
     def __init__(self, get_response):
          self.response = get_response

     def __call__(self, request):
         request.user = User()
         return self.response(request)

And also don't forget to modify your settings middleware and deactivate django.contrib.auth and add auto_auth

Chiheb Nexus
  • 9,104
  • 4
  • 30
  • 43
-1

For all using Django 3.0,

comment out this code AUTH_USER_MODEL = 'customUser' in your settings.py and create a superuser (python manage.py createsuperuser) with the default user model first.

After creating the superuser then uncomment this code AUTH_USER_MODEL = 'customUser'.

This happened to me and that's what I did with Django 3.0

You should be good to go. Hope it helps

Qcophie
  • 9
  • 1
  • 1
    not recommended at all, this will lead to two user model at one time. this can lead to great inconsistencies as you scale up. I HIGHLY SUGGEST you refactor your code to remove that!! – emanuel sanga Sep 11 '21 at 21:07