Extending the User model with custom fields in Django

后端 未结 13 1405
别那么骄傲
别那么骄傲 2020-11-21 23:28

What\'s the best way to extend the User model (bundled with Django\'s authentication app) with custom fields? I would also possibly like to use the email as the username (fo

相关标签:
13条回答
  • 2020-11-21 23:59

    Since Django 1.5 you may easily extend the user model and keep a single table on the database.

    from django.contrib.auth.models import AbstractUser
    from django.db import models
    from django.utils.translation import ugettext_lazy as _
    
    class UserProfile(AbstractUser):
        age = models.PositiveIntegerField(_("age"))
    

    You must also configure it as current user class in your settings file

    # supposing you put it in apps/profiles/models.py
    AUTH_USER_MODEL = "profiles.UserProfile"
    

    If you want to add a lot of users' preferences the OneToOneField option may be a better choice thought.

    A note for people developing third party libraries: if you need to access the user class remember that people can change it. Use the official helper to get the right class

    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    0 讨论(0)
  • 2020-11-21 23:59

    Simple and effective approach is models.py

    from django.contrib.auth.models import User
    class CustomUser(User):
         profile_pic = models.ImageField(upload_to='...')
         other_field = models.CharField()
    
    0 讨论(0)
  • 2020-11-22 00:00

    New in Django 1.5, now you can create your own Custom User Model (which seems to be good thing to do in above case). Refer to 'Customizing authentication in Django'

    Probably the coolest new feature on 1.5 release.

    0 讨论(0)
  • 2020-11-22 00:02

    The least painful and indeed Django-recommended way of doing this is through a OneToOneField(User) property.

    Extending the existing User model

    If you wish to store information related to User, you can use a one-to-one relationship to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.

    That said, extending django.contrib.auth.models.User and supplanting it also works...

    Substituting a custom User model

    Some kinds of projects may have authentication requirements for which Django’s built-in User model is not always appropriate. For instance, on some sites it makes more sense to use an email address as your identification token instead of a username.

    [Ed: Two warnings and a notification follow, mentioning that this is pretty drastic.]

    I would definitely stay away from changing the actual User class in your Django source tree and/or copying and altering the auth module.

    0 讨论(0)
  • 2020-11-22 00:02

    It's too late, but my answer is for those who search for a solution with a recent version of Django.

    models.py:

    from django.db import models
    from django.contrib.auth.models import User
    from django.db.models.signals import post_save
    from django.dispatch import receiver
    
    
    class Profile(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE)
        extra_Field_1 = models.CharField(max_length=25, blank=True)
        extra_Field_2 = models.CharField(max_length=25, blank=True)
    
    
    @receiver(post_save, sender=User)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            Profile.objects.create(user=instance)
    
    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        instance.profile.save()
    

    you can use it in templates like this:

    <h2>{{ user.get_full_name }}</h2>
    <ul>
      <li>Username: {{ user.username }}</li>
      <li>Location: {{ user.profile.extra_Field_1 }}</li>
      <li>Birth Date: {{ user.profile.extra_Field_2 }}</li>
    </ul>
    

    and in views.py like this:

    def update_profile(request, user_id):
        user = User.objects.get(pk=user_id)
        user.profile.extra_Field_1 = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit...'
        user.save()
    
    0 讨论(0)
  • 2020-11-22 00:09

    The below one is another approach to extend an User. I feel it is more clear,easy,readable then above two approaches.

    http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/

    Using above approach:

    1. you don't need to use user.get_profile().newattribute to access the additional information related to the user
    2. you can just directly access additional new attributes via user.newattribute
    0 讨论(0)
提交回复
热议问题