Django User and CustomUser

Custom users examples

Bas operations with a custom user

[8]: user = User.objects.get(username="pvergain")

In [9]: user.get_all_permissions()
Out[9]:
{'accounts.add_user',
 'accounts.change_user',
 'accounts.delete_user',
 'accounts.view_user',
 'admin.add_logentry',
 'admin.change_logentry',
 'admin.delete_logentry',
 'admin.view_logentry',

Ajout d’un groupe pour un utilisateur

In [1]: g1 = Group.objects.create(name='test_create_groupe')

In [2]: g1
Out[2]: <Group: test_create_groupe>

In [3]: u=User.objects.get(username='pvergain')

In [7]: u.groups.add(g1)

Lister tous les groupes d’un utilisateur ( groups )

In [19]: u.groups.all()
Out[19]: <QuerySet [<Group: test_create_groupe>]>

Description

class contrib.auth.base_user.BaseUserManager

 1 from django.utils.crypto import get_random_string, salted_hmac
 2
 3 class BaseUserManager(models.Manager):
 4
 5     @classmethod
 6     def normalize_email(cls, email):
 7         """
 8         Normalize the email address by lowercasing the domain part of it.
 9         """
10         email = email or ''
11         try:
12             email_name, domain_part = email.strip().rsplit('@', 1)
13         except ValueError:
14             pass
15         else:
16             email = email_name + '@' + domain_part.lower()
17         return email
18
19     def make_random_password(self, length=10,
20                              allowed_chars='abcdefghjkmnpqrstuvwxyz'
21                                            'ABCDEFGHJKLMNPQRSTUVWXYZ'
22                                            '23456789'):
23         """
24         Generate a random password with the given length and given
25         allowed_chars. The default value of allowed_chars does not have "I" or
26         "O" or letters and digits that look similar -- just to avoid confusion.
27         """
28         return get_random_string(length, allowed_chars)
29
30     def get_by_natural_key(self, username):
31         return self.get(**{self.model.USERNAME_FIELD: username})

class contrib.auth.base_user.AbstractBaseUser

 1 class AbstractBaseUser(models.Model):
 2     password = models.CharField(_('password'), max_length=128)
 3     last_login = models.DateTimeField(_('last login'), blank=True, null=True)
 4
 5     is_active = True
 6
 7     REQUIRED_FIELDS = []
 8
 9     # Stores the raw password if set_password() is called so that it can
10     # be passed to password_changed() after the model is saved.
11     _password = None
12
13     class Meta:
14         abstract = True
15
16     def __str__(self):
17         return self.get_username()
18
19     def save(self, *args, **kwargs):
20         super().save(*args, **kwargs)
21         if self._password is not None:
22             password_validation.password_changed(self._password, self)
23             self._password = None
24
25     def get_username(self):
26         """Return the username for this User."""
27         return getattr(self, self.USERNAME_FIELD)
28
29     def clean(self):
30         setattr(self, self.USERNAME_FIELD, self.normalize_username(self.get_username()))
31
32     def natural_key(self):
33         return (self.get_username(),)
34
35     @property
36     def is_anonymous(self):
37         """
38         Always return False. This is a way of comparing User objects to
39         anonymous users.
40         """
41         return False
42
43     @property
44     def is_authenticated(self):
45         """
46         Always return True. This is a way to tell if the user has been
47         authenticated in templates.
48         """
49         return True
50
51     def set_password(self, raw_password):
52         self.password = make_password(raw_password)
53         self._password = raw_password
54
55     def check_password(self, raw_password):
56         """
57         Return a boolean of whether the raw_password was correct. Handles
58         hashing formats behind the scenes.
59         """
60         def setter(raw_password):
61             self.set_password(raw_password)
62             # Password hash upgrades shouldn't be considered password changes.
63             self._password = None
64             self.save(update_fields=["password"])
65         return check_password(raw_password, self.password, setter)
66
67     def set_unusable_password(self):
68         # Set a value that will never be a valid hash
69         self.password = make_password(None)
70
71     def has_usable_password(self):
72         """
73         Return False if set_unusable_password() has been called for this user.
74         """
75         return is_password_usable(self.password)
76
77     def get_session_auth_hash(self):
78         """
79         Return an HMAC of the password field.
80         """
81         key_salt = "django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash"
82         return salted_hmac(key_salt, self.password).hexdigest()
83
84     @classmethod
85     def get_email_field_name(cls):
86         try:
87             return cls.EMAIL_FIELD
88         except AttributeError:
89             return 'email'
90
91     @classmethod
92     def normalize_username(cls, username):
93         return unicodedata.normalize('NFKC', username) if isinstance(username, str) else username

class contrib.auth.models.AbstractUser

 1 class AbstractUser(AbstractBaseUser, PermissionsMixin):
 2     """
 3     An abstract base class implementing a fully featured User model with
 4     admin-compliant permissions.
 5
 6     Username and password are required. Other fields are optional.
 7     """
 8     username_validator = UnicodeUsernameValidator()
 9
10     username = models.CharField(
11         _('username'),
12         max_length=150,
13         unique=True,
14         help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
15         validators=[username_validator],
16         error_messages={
17             'unique': _("A user with that username already exists."),
18         },
19     )
20     first_name = models.CharField(_('first name'), max_length=30, blank=True)
21     last_name = models.CharField(_('last name'), max_length=150, blank=True)
22     email = models.EmailField(_('email address'), blank=True)
23     is_staff = models.BooleanField(
24         _('staff status'),
25         default=False,
26         help_text=_('Designates whether the user can log into this admin site.'),
27     )
28     is_active = models.BooleanField(
29         _('active'),
30         default=True,
31         help_text=_(
32             'Designates whether this user should be treated as active. '
33             'Unselect this instead of deleting accounts.'
34         ),
35     )
36     date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
37
38     objects = UserManager()
39
40     EMAIL_FIELD = 'email'
41     USERNAME_FIELD = 'username'
42     REQUIRED_FIELDS = ['email']
43
44     class Meta:
45         verbose_name = _('user')
46         verbose_name_plural = _('users')
47         abstract = True
48
49     def clean(self):
50         super().clean()
51         self.email = self.__class__.objects.normalize_email(self.email)
52
53     def get_full_name(self):
54         """
55         Return the first_name plus the last_name, with a space in between.
56         """
57         full_name = '%s %s' % (self.first_name, self.last_name)
58         return full_name.strip()
59
60     def get_short_name(self):
61         """Return the short name for the user."""
62         return self.first_name
63
64     def email_user(self, subject, message, from_email=None, **kwargs):
65         """Send an email to this user."""
66         send_mail(subject, message, from_email, [self.email], **kwargs)

class contrib.auth.models.User

1 class User(AbstractUser):
2     """
3     Users within the Django authentication system are represented by this
4     model.
5
6     Username and password are required. Other fields are optional.
7     """
8     class Meta(AbstractUser.Meta):
9         swappable = 'AUTH_USER_MODEL'

class contrib.auth.models.AnonymousUser

 1 class AnonymousUser:
 2     id = None
 3     pk = None
 4     username = ''
 5     is_staff = False
 6     is_active = False
 7     is_superuser = False
 8     _groups = EmptyManager(Group)
 9     _user_permissions = EmptyManager(Permission)
10
11     def __str__(self):
12         return 'AnonymousUser'
13
14     def __eq__(self, other):
15         return isinstance(other, self.__class__)
16
17     def __hash__(self):
18         return 1  # instances always return the same hash value
19
20     def __int__(self):
21         raise TypeError('Cannot cast AnonymousUser to int. Are you trying to use it in place of User?')
22
23     def save(self):
24         raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
25
26     def delete(self):
27         raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
28
29     def set_password(self, raw_password):
30         raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
31
32     def check_password(self, raw_password):
33         raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
34
35     @property
36     def groups(self):
37         return self._groups
38
39     @property
40     def user_permissions(self):
41         return self._user_permissions
42
43     def get_group_permissions(self, obj=None):
44         return set()
45
46     def get_all_permissions(self, obj=None):
47         return _user_get_all_permissions(self, obj=obj)
48
49     def has_perm(self, perm, obj=None):
50         return _user_has_perm(self, perm, obj=obj)
51
52     def has_perms(self, perm_list, obj=None):
53         return all(self.has_perm(perm, obj) for perm in perm_list)
54
55     def has_module_perms(self, module):
56         return _user_has_module_perms(self, module)
57
58     @property
59     def is_anonymous(self):
60         return True
61
62     @property
63     def is_authenticated(self):
64         return False
65
66     def get_username(self):
67         return self.username

UserManager

 1 class UserManager(BaseUserManager):
 2     use_in_migrations = True
 3
 4     def _create_user(self, username, email, password, **extra_fields):
 5         """
 6         Create and save a user with the given username, email, and password.
 7         """
 8         if not username:
 9             raise ValueError('The given username must be set')
10         email = self.normalize_email(email)
11         username = self.model.normalize_username(username)
12         user = self.model(username=username, email=email, **extra_fields)
13         user.set_password(password)
14         user.save(using=self._db)
15         return user
16
17     def create_user(self, username, email=None, password=None, **extra_fields):
18         extra_fields.setdefault('is_staff', False)
19         extra_fields.setdefault('is_superuser', False)
20         return self._create_user(username, email, password, **extra_fields)
21
22     def create_superuser(self, username, email, password, **extra_fields):
23         extra_fields.setdefault('is_staff', True)
24         extra_fields.setdefault('is_superuser', True)
25
26         if extra_fields.get('is_staff') is not True:
27             raise ValueError('Superuser must have is_staff=True.')
28         if extra_fields.get('is_superuser') is not True:
29             raise ValueError('Superuser must have is_superuser=True.')
30
31         return self._create_user(username, email, password, **extra_fields)

Gestion des utilisateurs dans le site d’administration

Quand django.contrib.admin et django.contrib.auth sont les deux installés, le site d’administration offre une interface pratique pour afficher et gérer les utilisateurs, les groupes et les permissions.

Les utilisateurs peuvent être créés et supprimés comme tout autre modèle Django.

Des groupes peuvent être créés et des permissions peuvent être attribuées aux utilisateurs et aux groupes.

Les modifications de modèles effectuées dans l’administration par les utilisateurs sont également journalisées et affichées.