djangodjango-modelsusermanager

Django best practices regarding custom User models


This is more of a general best practices question. When you start a new project in Django, do you generally create a custom User model, or rely on the default one?

Personally it seems cleaner to me if I don't mess with the default User model. If there are any additional attributes I want to add, I feel it is simpler to add a Profile or UserInfo model with a one-to-one/foreign key relation with a User.

A lot of articles I've read about Django, however, disagree with this. Apparently it is recommended to build a custom User model? I'm curious about what everyone does, and what exactly I'm missing out on if I make either of these choices.


Solution

  • A custom user model is a good practice when you have to add new fields or logic to the User model (such as loging in using email instead of username or adding new permisions). If you application is simple and you dont have to add new fields, you can use the default user model. Other solution is to keep the user model intact and create an "User Profile" model with a OneToOne relation to User, but you would have to create the profile manually and add it to the User, or maybe use django signals to create an User profile every time a new user is created. I personaly don't recommend this last solution. So, you should create a custom User model if you have to add new fields or logic, otherwise stick to the Default User Model. If you use a custom model remember to add the new fields to the admin site This is an example

        class User(AbstractUser):
            worker = models.OneToOneField(WorkerModel, on_delete=models.CASCADE, 
                        related_name="user", verbose_name=_("Trabajador"), null=True, blank=True)
        
            job = models.CharField(verbose_name="Cargo",max_length=50, null=True, blank=True)
            department = models.CharField(verbose_name="Departamento",max_length=50, null=True, blank=True)
            avatar = models.ImageField(verbose_name="Imagen", upload_to="user_avatar",
                                                        null=True, blank=True)
            class Meta:
                default_permissions = ()
                verbose_name="Usuario"
                verbose_name_plural="Usuarios"
                permissions = (
                    ("secretario", "Secretario(a)"),
                    ("director", "Director"),
                
                )
    
    from django.contrib import admin
    from django.contrib.auth.admin import UserAdmin
    from .models import User #, UserProfileModel
    from django.utils.translation import gettext, gettext_lazy as _
    
    class UserAdminInherited(UserAdmin):
        autocomplete_fields = ['worker']
        fieldsets = (
            (None, {'fields': ('username', 'password')}),
            (_('Personal info'), {'fields': ('first_name', 'last_name', 'email','job','department','avatar')}),
            (_('Worker info'), {'fields': ('worker',)}),
            (_('Permissions'), {
                'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
            }),
            (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
        )
    
    admin.site.register(User, UserAdminInherited)