1

I've been going back and forward between two tutorials on creating custom user models:

https://simpleisbetterthancomplex.com/tutorial/2018/01/18/how-to-implement-multiple-user-types-with-django.html

and https://wsvincent.com/django-tips-custom-user-model/

So far here is my code:

Model:

class CustomUser(AbstractUser):
    is_admin = models.BooleanField('admin status', default=False)
    is_areamanager = models.BooleanField('areamanager status', default=False)
    is_sitemanager = models.BooleanField('sitemanager status', default=False)

Form:

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm.Meta):
        model = CustomUser

class CustomUserChangeForm(UserChangeForm):

    class Meta(UserChangeForm.Meta):
        model = CustomUser

Admin:

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ['email', 'username',]

admin.site.register(CustomUser, CustomUserAdmin)

I have hit a bit of a wall at this point. I'm not sure what direction to go in with restricting content to users. My general idea is I want admins to access everything, area managers to have the next level of access, site manager after that, then regular users (false on all boolean checks) to have base privileges.

Is this the best route to go for this kind of implementation? Where should I go from here and why?

CalMac
  • 449
  • 1
  • 4
  • 30

1 Answers1

1

Don't extend the AbstractUser, user Django built-in groups and permissions to create class of users with different privileges: https://docs.djangoproject.com/en/3.0/topics/auth/default/#groups

If you need to add more info to you user, a common pattern is to create a UserProfile:

class UserProfile(models.Model):  
    user = models.OneToOneField(User, related_name='profile')
    address = models.CharField(max_length=140)  
    age = ...

A couple of suggestions:

  • Use the AbstractUser just in case of specific use cases (for example when you need to customize the AuthenticationBackend)
  • Use the user ID and not the user profile id as FK in models (it is more easy to retrieve it from requests)
  • For basic use cases just adding a 'role' field to the UserProfile is enough for implementing a simple logic
Dos
  • 2,250
  • 1
  • 29
  • 39
  • Thanks for your answer. Could you expand on using the built in groups feature? For example if I had a template page with 3 sections of information and I want only admins to access 2 out of the 3, with everyone else accessing just 1. How would I restrict them if I had set up users into admin/user/manager groups like above? – CalMac Jan 27 '20 at 16:38
  • 1
    If the only groups are admin/not-admin, I suggest to use the built-in 'is_staff' attribute. You can just set it up to True for your admin user (NB: staff can access the admin panel) and then hide buttons in the template: {% if request.user.is_admin %}{% endif %} – Dos Jan 27 '20 at 21:46
  • I'll have 4 groups I think. Or possibly 3 (Admin, SiteManager, AreaManager) with regular User as a default state. Would this implementation work in this situation? – CalMac Jan 28 '20 at 08:19
  • 1
    In this case you can use Groups and Permissions. They help you to limit the access to specific model and how the user can add/view/update/delete these models. In this post you have some good examples on how you can use these rules in a template: https://stackoverflow.com/questions/34571880/how-to-check-in-template-if-user-belongs-to-a-group Hope this will be helpful :) – Dos Jan 28 '20 at 08:46
  • Thank you! This has been really helpful. – CalMac Jan 28 '20 at 08:50