From c8aaf33170d6ec24f8c31898f9dd37af315d6847 Mon Sep 17 00:00:00 2001 From: Michel Wilhelm Date: Wed, 4 Nov 2020 21:53:20 -0300 Subject: [PATCH] Adding a custom User model --- app/settings.py | 3 +++ core/__init__.py | 0 core/admin.py | 16 +++++++++++++ core/apps.py | 5 ++++ core/managers.py | 29 +++++++++++++++++++++++ core/migrations/0001_initial.py | 42 +++++++++++++++++++++++++++++++++ core/migrations/__init__.py | 0 core/models.py | 41 ++++++++++++++++++++++++++++++++ core/tests.py | 3 +++ core/views.py | 3 +++ 10 files changed, 142 insertions(+) create mode 100644 core/__init__.py create mode 100644 core/admin.py create mode 100644 core/apps.py create mode 100644 core/managers.py create mode 100644 core/migrations/0001_initial.py create mode 100644 core/migrations/__init__.py create mode 100644 core/models.py create mode 100644 core/tests.py create mode 100644 core/views.py diff --git a/app/settings.py b/app/settings.py index e4f896c..cb66b0c 100644 --- a/app/settings.py +++ b/app/settings.py @@ -22,6 +22,7 @@ INSTALLED_APPS = [ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", + "core", ] MIDDLEWARE = [ @@ -54,6 +55,8 @@ TEMPLATES = [ WSGI_APPLICATION = "app.wsgi.application" +AUTH_USER_MODEL = "core.User" + # Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/admin.py b/core/admin.py new file mode 100644 index 0000000..699edc2 --- /dev/null +++ b/core/admin.py @@ -0,0 +1,16 @@ +from django.contrib import admin + +from .models import User + + +@admin.register(User) +class UserAdmin(admin.ModelAdmin): + search_fields = ("id", "email", "first_name", "last_name") + list_display = ( + "id", + "first_name", + "last_name", + "is_active", + "email", + "date_joined", + ) diff --git a/core/apps.py b/core/apps.py new file mode 100644 index 0000000..26f78a8 --- /dev/null +++ b/core/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + name = 'core' diff --git a/core/managers.py b/core/managers.py new file mode 100644 index 0000000..cb82257 --- /dev/null +++ b/core/managers.py @@ -0,0 +1,29 @@ +from django.contrib.auth.base_user import BaseUserManager + + +class UserManager(BaseUserManager): + use_in_migrations = True + + def _create_user(self, email, password, **extra_fields): + """ + Creates and saves a User with the given email and password. + """ + if not email: + raise ValueError("The given email must be set") + email = self.normalize_email(email) + user = self.model(email=email, **extra_fields) + user.set_password(password) + user.save(using=self._db) + return user + + def create_user(self, email, password=None, **extra_fields): + extra_fields.setdefault("is_superuser", False) + return self._create_user(email, password, **extra_fields) + + def create_superuser(self, email, password, **extra_fields): + extra_fields.setdefault("is_superuser", True) + + if extra_fields.get("is_superuser") is not True: + raise ValueError("Superuser must have is_superuser=True.") + + return self._create_user(email, password, **extra_fields) diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..cfa9dea --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# Generated by Django 3.1.3 on 2020-11-05 00:51 + +import core.managers +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')), + ('email', models.EmailField(max_length=254, unique=True, verbose_name='E-mail')), + ('first_name', models.CharField(blank=True, max_length=30, verbose_name='First name')), + ('last_name', models.CharField(blank=True, max_length=30, verbose_name='Last name')), + ('date_joined', models.DateTimeField(auto_now_add=True, verbose_name='date joined')), + ('is_active', models.BooleanField(default=True, verbose_name='User active?')), + ('is_staff', models.BooleanField(default=False, verbose_name='Staff?')), + ('is_superuser', models.BooleanField(default=False, verbose_name='Superuser?')), + ('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={ + 'verbose_name': 'User', + 'verbose_name_plural': 'Users', + 'db_table': 'users', + 'ordering': ['first_name', 'last_name'], + }, + managers=[ + ('objects', core.managers.UserManager()), + ], + ), + ] diff --git a/core/migrations/__init__.py b/core/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/models.py b/core/models.py new file mode 100644 index 0000000..c89b937 --- /dev/null +++ b/core/models.py @@ -0,0 +1,41 @@ +from django.db import models +from django.contrib.auth.models import PermissionsMixin +from django.contrib.auth.base_user import AbstractBaseUser + +from .managers import UserManager + + +class User(AbstractBaseUser, PermissionsMixin): + email = models.EmailField("E-mail", unique=True) + + first_name = models.CharField("First name", max_length=30, blank=True) + last_name = models.CharField("Last name", max_length=30, blank=True) + + date_joined = models.DateTimeField("date joined", auto_now_add=True) + + is_active = models.BooleanField("User active?", default=True) + is_staff = models.BooleanField("Staff?", default=False) + is_superuser = models.BooleanField("Superuser?", default=False) + + objects = UserManager() + + USERNAME_FIELD = "email" + + class Meta: + ordering = ["first_name", "last_name"] + verbose_name = "User" + verbose_name_plural = "Users" + db_table = "users" + + def get_full_name(self): + """ + Returns the first_name plus the last_name, with a space in between. + """ + full_name = f"{self.first_name} {self.last_name}" + return full_name.strip() + + def get_short_name(self): + """ + Returns the short name for the user. + """ + return self.first_name or "Unamed" diff --git a/core/tests.py b/core/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/core/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/core/views.py b/core/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/core/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.