[Answer]-Separate admin site for users

1👍

  1. Having two admin interfaces is probably silly. Django’s admin supports robust user permissions.

  2. Keep username’s unique, and use an email authentication backend. This lets users user their email address if they want to. Since, at least in 1.4, email addresses didn’t have to be unique, you’re in the clear.

  3. Here’s a simple email auth backend:

    from django.contrib.auth.backends import ModelBackend
    from django.contrib.admin.models import User
    
    class EmailAuthBackEnd(ModelBackend):
        def authenticate(self, email=None, password=None,**kwargs):
            try:
                user = User.objects.get(email=email)  
                if user.check_password(password):
                    return user
                return None
            except User.DoesNotExist:
                return None
    
  4. Add the above to a file called backends.py in one of your apps, then add this to your settings.py:

    AUTHENTICATION_BACKENDS = AUTHENTICATION_BACKENDS + ('app.backends.EmailAuthBackEnd',)
    
  5. On the whole unique passwords thing … that’s tricky to deal with. You could subclass Django’s user model, and change password to a unique string, or you could patch PSQL manually to enforce that constraint. OR you could be lazy, assume passwords will be assigned, assign every user a random username, safe in the knowledge you can always login and ‘fix’ problem accounts.

0👍

I would suggest that you allow users to retain their current credentials (that will be a big plus from a usability point of view), and then adjust what they see depending on where they’re coming from. There’s lots of methods on django’s ModelAdmin that you can override. So on a model by model basis you could do –

class MyModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        self.exclude = []
        if request.META(REMOTE_ADDR) not in [# add list of internal ip's here]
            self.exclude.append('field_to_hide')
        return super(MyModelAdmin, self).get_form(request, obj, **kwargs)

As in the docs example here. (also have a look at the list of http headers here to get an idea of how you might make your check)

If you want to change the list of objects available on the main admin menu then, look at overriding the AdminSite, to add your own get_urls() method that provides similar functionality to the individual get_form method I’ve suggested above.

Leave a comment