Simple Custom User Model In Django :: CookBook
Tags: django, python, authentication, djangoauth
Published: 2020-11-11 11:08:21

# Custom User Model in Django.

## Steps Involve.
- Creating custom user model and manager.
- Update the settings.py
- Customize the `UserCreationForm` and `UserChangeForm`.
- Finally update the admin.py file for custom user model.

## Models.py
```python
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from app.managers import CustomUserManager

class CustomUser(AbstractBaseUser, PermissionsMixin):
    phone_no = models.CharField(_("Phone Number"), unique=True, max_length=10)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    date_joined = models.DateTimeField(default=timezone.now)

    USERNAME_FIELD = 'phone_no'
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    def __str__(self):
        return self.phone_no
```

## Manager.py
```python
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _


class CustomUserManager(BaseUserManager):
    def create_user(self, phone_no, password, **extra_fields):
        if not phone_no:
            raise ValueError(_("The phone no. must be provided."))
        if len(phone_no) != 10:
            raise ValueError(_("The Phone No Should be 10 digits long."))
        user = self.model(phone_no=phone_no, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, phone_no, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True'))

        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True'))

        return self.create_user(phone_no, password, **extra_fields)
    
```

## Settings.py
```python
AUTH_USER_MODEL = 'app.CustomUser'
```

## Forms.py
```python
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from app.models import CustomUser

class CustomUserCreationForm(UserCreationForm):
    class Meta(UserCreationForm):
        model = CustomUser
        fields = ('phone_no',)
    
class CustomUserChangeForm(UserChangeForm):
    class Meta:
        model = CustomUser
        fields = ('phone_no', )
```

## Admin.py
```python
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserChangeForm, CustomUserCreationForm
from .models import CustomUser


class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ('phone_no', 'is_staff', 'is_active')
    list_filter = ('phone_no', 'is_staff', 'is_active')

    fieldsets = (
        (None, {'fields': ('phone_no', 'password')}),
        ('Permissions', {'fields': ('is_staff', 'is_active')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide', ),
            'fields': ('phone_no', 'password1', 'password2', 'is_staff', 'is_active')
        }),
    )
    search_fields = ('phone_no', )
    ordering = ('phone_no', )


admin.site.register(CustomUser, CustomUserAdmin)
```

## Quick Note:
I wanted to make user model as simple as possible so this is what i did, create a custom user model with basically only two fields `phone_no` and `password`.


- [@vivekascoder](https://instagram.com/vivekascoder)