Вопрос

I am new to Django and need to use an email address as a username for my app - plus add some custom fields. So I am following the full example in django docs to make a custom user model.

I am very worried about the part in the example that says:

This example illustrates how most of the components work together, but is not intended to be copied directly into projects for production use.

I am not sure what else is needed in order to make the user model production ready.

Is the example missing some crucial security features? (I would like my custom model and authentication to be as good as the default Django one.)

Does anyone have an example that is production ready?

Это было полезно?

Решение

In the end, what I did was follow the full example in the django website, and compare my code with the default Django user model. I believe the default Django user model is production ready, and really, the only difference from that and the custom user model is the use of email as username, so I feel quite reassured that my custom user model is production ready.

Here is my code:

in models.py

from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.core.mail import send_mail

class MyUserManager(BaseUserManager):
    def create_user(self, email, password=None):
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        """
        Creates and saves a superuser with the given email and password.
        """
        user = self.create_user(email,
            password=password
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

class MyUser(AbstractBaseUser):
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
    email = models.EmailField(_('email address'), max_length=254, blank=False, unique=True, db_index=True)  
    is_active = models.BooleanField(_('active'), default=True,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    is_admin = models.BooleanField(default=False)
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
    gender_choices = (
        ('M', 'Male'),
        ('F', 'Female'),
        )
    gender = models.CharField(max_length=1, choices=gender_choices, blank=True)
    date_of_birth = models.DateField(null=True, blank=True)
    city = models.CharField(max_length=50, blank=True)
    phone_number = models.CharField(max_length=15, blank=True)
    description = models.TextField(blank=True)
    work = models.TextField(blank=True)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

    def get_full_name(self):
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        return self.first_name

    def email_user(self, subject, message, from_email=None):
        """
        Sends an email to this User.
        """
        send_mail(subject, message, from_email, [self.email])

    def __unicode__(self):
        return self.first_name + ' ' + self.last_name

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.is_admin

Also in my forms.py and views.py I used the User model, so I added the following:

from django.contrib.auth import get_user_model
User = get_user_model()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top