[Django]-Django best practices regarding custom User models

3πŸ‘

βœ…

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)
πŸ‘€Ernesto Ruiz

0πŸ‘

SOLID principles: the Single responsibility design pattern would advise having both the user model and the profile model, each of these should have only one responsibility. It makes it easier to manage your code and will minimize the potential for bugs.

Here are some great resources for more information on SOLID design principles:
https://www.freecodecamp.org/news/solid-principles-explained-in-plain-english/

https://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

Also a great resource for design patterns:
https://youtube.com/playlist?list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc

(Based on the "Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software" book by Eric Freeman & Elisabeth Robson.

All of these are some important principles for object-oriented programing. Most of the examples are in Java, but the concepts can be applied in any language. I hope these help in your future projects, too. These will make things much easier to reason about your code.

πŸ‘€Audrey_Dev

Leave a comment