Bläddra i källkod

Add Custom User Model

kaajavi 5 år sedan
förälder
incheckning
71f47546cd
5 ändrade filer med 139 tillägg och 21 borttagningar
  1. 91 1
      users/admin.py
  2. 7 13
      users/managers.py
  3. 34 0
      users/migrations/0001_initial.py
  4. 5 6
      users/models.py
  5. 2 1
      users/serializers.py

+ 91 - 1
users/admin.py

@@ -1,3 +1,93 @@
 from django.contrib import admin
+from django.contrib.auth.forms import ReadOnlyPasswordHashField
+from django.contrib.auth.models import Group
+from django import forms
+from .models import User
 
-# Register your models here.
+
+class UserCreationForm(forms.ModelForm):
+    """A form for creating new users. Includes all the required
+    fields, plus a repeated password."""
+    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
+    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
+
+    class Meta:
+        model = User
+        fields = ('email', 'age', 'name')
+
+    def clean_password2(self):
+        # Check that the two password entries match
+        password1 = self.cleaned_data.get("password1")
+        password2 = self.cleaned_data.get("password2")
+        if password1 and password2 and password1 != password2:
+            raise forms.ValidationError("Passwords don't match")
+        return password2
+
+
+    def save(self, commit=True):
+        # Save the provided password in hashed format
+        user = super(UserCreationForm, self).save(commit=False)
+        user.set_password(self.cleaned_data["password1"])
+        if commit:
+            user.save()
+        return user
+
+
+class UserChangeForm(forms.ModelForm):
+    """A form for updating users. Includes all the fields on
+    the user, but replaces the password field with admin's
+    password hash display field.
+    """
+    password = ReadOnlyPasswordHashField(label=("Password"),
+                                         help_text=("Raw passwords are not stored, so there is no way to see "
+                                                    "this user's password, but you can change the password "
+                                                    "using <a href=\"password/\">this form</a>."))
+
+    class Meta:
+        model = User
+        fields = ('email', 'age', 'name','password')
+
+    def clean_password(self):
+        # Regardless of what the user provides, return the initial value.
+        # This is done here, rather than on the field, because the
+        # field does not have access to the initial value
+        return self.initial["password"]
+
+
+class CustomUserAdmin(admin.ModelAdmin):
+    # The forms to add and change user instances
+    form = UserChangeForm
+    add_form = UserCreationForm
+    model = User
+    # The fields to be used in displaying the User model.
+    # These override the definitions on the base UserAdmin
+    # that reference specific fields on auth.User.
+    list_display = ('email', 'name', 'age', 'is_superuser')
+    list_filter = ('is_superuser',)
+    fieldsets = (
+        (None, {'fields': ('email', 'password')}),
+        ('Personal info', {'fields': ('name','age')}),
+    )
+    add_fieldsets = (
+        (None, {
+            'classes': ('wide',),
+            'fields': ('email', 'name','age', 'password1', 'password2')}
+         ),
+    )
+    search_fields = ('email',)
+    ordering = ('email',)
+    filter_horizontal = ()
+
+    def get_fieldsets(self, request, obj=None):
+        if not obj:
+            return self.add_fieldsets
+        return self.fieldsets
+
+    def get_form(self, request, obj=None, change=False, **kwargs):
+        if not obj:
+            return self.add_form
+        return self.form
+
+
+admin.site.register(User, CustomUserAdmin)
+admin.site.unregister(Group)

+ 7 - 13
users/managers.py

@@ -1,26 +1,17 @@
 """
-This module provides class definition to manage Employee objects.
+This module provides class definition to manage User objects.
 
 Available classes:
-- EmployeeQuerySet: define a collection of Employee objects.
-- BaseEmployeeManager: interface through which database query operations are
+- UserManager: interface through which database query operations are
                        provided to model.
-- PassThroughEmployeeManager: allow to call methods defined in EmployeeQuerySet
-                              from Manager.
 """
-
-from django.db.models import Manager
 from django.contrib.auth.models import BaseUserManager
-from django.db.models.query import QuerySet
-from django.utils.timezone import now
-
-
 
 
 class UserManager(BaseUserManager):
     """
     Interface through which database query operations are provided to
-    Employee model.
+    User model.
     """
 
     def _create_user(self, email, password, is_staff, is_superuser,
@@ -31,7 +22,10 @@ class UserManager(BaseUserManager):
         if not email:
             raise ValueError('Users must have an email address')
         email = self.normalize_email(email)
-        user = self.model(email=email, age=0,
+        name = ''
+        if is_superuser:
+            name='Super User'
+        user = self.model(email=email, age=0, name=name,
                           is_staff=is_staff, is_active=True,
                           is_superuser=is_superuser, **extra_fields)
         user.set_password(password)

+ 34 - 0
users/migrations/0001_initial.py

@@ -0,0 +1,34 @@
+# Generated by Django 3.1.3 on 2020-11-11 19:31
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('auth', '0012_alter_user_first_name_max_length'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='User',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('password', models.CharField(max_length=128, verbose_name='password')),
+                ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
+                ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
+                ('name', models.CharField(max_length=100, verbose_name='Name')),
+                ('email', models.EmailField(error_messages={'unique': 'This email already exists'}, max_length=255, unique=True, verbose_name='Email')),
+                ('age', models.PositiveSmallIntegerField(verbose_name='Age')),
+                ('is_staff', models.BooleanField(default=False, verbose_name='This user can see the admin panel?')),
+                ('is_active', models.BooleanField(default=False, verbose_name='Is Active')),
+                ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
+                ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+    ]

+ 5 - 6
users/models.py

@@ -1,9 +1,9 @@
 from django.db import models
-from django.contrib.auth.models import AbstractUser
+from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, AbstractUser
 from django.utils.translation import ugettext_lazy as _
 from .managers import UserManager
 
-class User(AbstractUser):
+class User(AbstractBaseUser, PermissionsMixin):
     """
         Holds information related to an user.
     """
@@ -11,13 +11,12 @@ class User(AbstractUser):
     USERNAME_FIELD = 'email'
 
     objects = UserManager()
-    name = models.CharField(_(u'Name'), max_length=100, blank=True)
+    name = models.CharField(_(u'Name'), max_length=100, unique=False)
+
     email = models.EmailField(verbose_name=_(u'Email'),
                               max_length=255, unique=True,
                               error_messages={'unique': _('This email already exists')})
-    age = models.PositiveSmallIntegerField(_('Age'), default=None, )
-    is_superuser = models.BooleanField(
-        _('This user is superuser?'), default=False)
+    age = models.PositiveSmallIntegerField(_('Age'))
     is_staff = models.BooleanField(
         _('This user can see the admin panel?'), default=False)
     is_active = models.BooleanField(_('Is Active'), default=False)

+ 2 - 1
users/serializers.py

@@ -7,4 +7,5 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
 
     class Meta:
         model = User
-        fields = ['name', 'email', 'age', 'url']
+        fields = ['name', 'email', 'age']
+