Reputation: 260
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.
Upvotes: 4
Views: 1435
Reputation: 27
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.
Upvotes: 0
Reputation: 820
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)
Upvotes: 4