Implementing Custom User Authentication in Django

Hello

I am building a web application with Django. Trying to implement user authentication using a custom user model instead of the default one.

I need guidance on the below points:

-How do I define a custom user model in Django? What fields are essential ; and what best practices should I follow?

-What changes do I need to make in the settings.py file to confirm Django uses my custom user model?

-How can I set up the authentication system to work with my custom user model?

I have referred https://docs.djangoproject.com/en/5.0/topics/auth/customizing/#:~:text=The%20best%20way%20to%20deal,time%20a%20user%20logs%20in salesforce marketing cloud guide but still need help.

Thanks in advance for your help!

Best regards,

nolanmaris

(I’m simply going to assume that you are using a translator software to use this forum, and as you already know, this is a Turkish forum, so I will respond in Turkish.)

Django’da custom user model kullanmak cok basit. AbstractUser veya AbstractBaseUser siniflarindan birini inherit eden bir model olusturuyorsunuz, daha sonra settings.py dosyasinda Django’ya custom bir kullanici modeliniz oldugunu soyluyorsunuz:

AUTH_USER_MODEL = 'accounts.CustomUser' # Uygulama (app) ismi ve model adi

Ustteki degisiklikleri yaptiktan sonra, modeliniz dogruysa Django bu modeli authentication icin kullanacaktir.

Yardima ihtiyaciniz oldugunu soyluyorsunuz ama ustte yazdigim sey basit bir Google aramasiyla da bulunabiliyor. Hangi asamada nasil, neden sorun yasadiginizi soylerseniz daha kolay yardimci olabiliriz. Soru Sorarken Sikca Dusulen Hatalar’a da goz atmayi unutmayin.

1 Beğeni

Hello @nolanmaris, here is the custom user model I usually use;

models.py

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager,

#company model
class Sirket(models.Model):
    sirketAdi   = models.CharField(max_length=30, verbose_name='Şirket Adı')
    slug        = AutoSlugField(populate_from = "sirketAdi",always_update=True, unique=True)

    class Meta:
        db_table = 'm_auth_sirket'
        verbose_name = 'Şirket'
        verbose_name_plural = '01 - Şirketler'

    def __str__(self):
        return self.sirketAdi

# department model
class Departman(models.Model):

    sirketAdi       = models.ForeignKey(Sirket, on_delete=models.CASCADE, verbose_name="Şirket")
    departmanAdi    = models.CharField(max_length=100, verbose_name='Departman Adı')
    slug            = AutoSlugField(populate_from = "departmanAdi",always_update=True, unique=True)

    class Meta:
        db_table            = "m_auth_departman"
        verbose_name        = 'Departman'
        verbose_name_plural = '02 - Departmanlar'

    def __str__(self):
        return self.departmanAdi
    
# Title model
class Unvan(models.Model):
    sirketAdi       = models.ForeignKey(Sirket, on_delete=models.CASCADE, verbose_name="Şirket")
    departmanAdi    = models.ForeignKey(Departman, on_delete=models.CASCADE,verbose_name="Departman")
    unvanAdi        = models.CharField(max_length=150, verbose_name="Unvan Adı")
    slug            = AutoSlugField(populate_from = "unvanAdi",always_update=True, unique=True)

    class Meta:
        db_table            = "m_auth_unvanlar"
        verbose_name        = 'Unvan'
        verbose_name_plural = '03 - Unvanlar'

    def __str__(self):
        return self.unvanAdi

# manager
class AccountManager(BaseUserManager):
    def create_user(self, email, adSoyad, password):
        if not email:
            raise ValueError("E-posta adresi zorunludur")
        if not adSoyad:
            raise ValueError("Kullanıcı adı yazılmalıdır.")
        
        user = self.model(
            email = self.normalize_email(email),
            adSoyad = adSoyad,
        )

        user.set_password(password)
        user.save(using=self.db)
        return user
    
    def create_superuser(self, email, adSoyad, password):
        user = self.create_user(
            email=self.normalize_email(email),
            adSoyad=adSoyad,
            password=password,
        )

        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True

        user.save(using=self.db)
        return user

# custom user account model
class Account(AbstractBaseUser, PermissionsMixin):
    email       = models.EmailField(max_length=100, unique=True)
    adSoyad     = models.CharField(max_length=50)
    foto        = models.ImageField(upload_to='profil_foto/', null=True, blank=True)
    linkedIn    = models.URLField(max_length=100, null=True, blank=True)
    slug        = AutoSlugField(populate_from = "email",always_update=True, unique=True)
    
    sirket      = models.ForeignKey(Sirket, verbose_name="Çalıştığı Şirket", null=True, blank=True, on_delete=models.CASCADE)
    sicilNo     = models.CharField(max_length=5, verbose_name="Sicil No", null=True, blank=True)
    departman   = models.ForeignKey(Departman, verbose_name="Departmanı", null=True, blank=True, on_delete=models.CASCADE)
    lokasyon    = models.CharField(max_length=50, verbose_name="Lokasyon", null=True, blank=True)
    lokasyon_corlu = models.BooleanField(default=False, verbose_name="Çorlu Lokasyonu")
    unvan       = models.ForeignKey(Unvan,verbose_name="Unvanı", null=True, blank=True, on_delete=models.CASCADE)
    telKisisel  = models.CharField(max_length=12,verbose_name="Kişisel GSM", null=True,blank=True)
    telGSM      = models.CharField(max_length=12,verbose_name="GSM Numarası", null=True,blank=True)
    telDahili   = models.CharField(max_length=5,verbose_name="Dahili Tel", null=True, blank=True)

    dateDT      = models.DateField(auto_now=False, auto_now_add=False, verbose_name="Doğum Tarihi", null=True, blank=True)
    dateStart   = models.DateField(auto_now=False, auto_now_add=False, verbose_name="Başlama Tarihi", null=True, blank=True)
    dateJoin    = models.DateField(auto_now=True, verbose_name="Kayıt Tarihi", null=True, blank=True)
    dateLeft    = models.DateField(auto_now=False, auto_now_add=False, verbose_name="Ayrılma Tarihi", null=True, blank=True)

    is_active       = models.BooleanField(default=True)
    is_superuser    = models.BooleanField(default=False)
    is_admin        = models.BooleanField(default=False)
    is_staff        = models.BooleanField(default=False)


    objects = AccountManager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['adSoyad']

    class Meta:
        db_table            = "m_auth_account"
        verbose_name        = "Kullanıcı"
        verbose_name_plural = "04 - Kullanıcılar"
    
    def __str__(self) -> str:
        return self.adSoyad

admin.py

from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

class CustomUserAdmin(BaseUserAdmin):
    list_display = ['adSoyad', 'email', 'is_admin','id', 'is_active', 'sirket']

    search_fields = ['email', 'adSoyad']

    readonly_fields = ['dateJoin']

    fieldsets = (
        ("Kişisel Bilgiler",
         {"fields": ("adSoyad","email","telKisisel", "password", "linkedIn","foto")}),

        ("Organizasyon Bilglieri",
         {"fields": ("sirket","sicilNo", "departman","unvan", "telGSM", "telDahili", "lokasyon","lokasyon_corlu")}),

        ("Önemli Tarihler",
         {"fields": ("dateDT", "dateStart", "dateLeft","dateJoin")}),

        ("İzinler",
         {"fields": ("is_staff","is_active", "is_superuser", "is_admin")}),

        ('Groups', 
         {'fields': ('groups',)}),

        ('Permissions', 
         {'fields': ('user_permissions',)}),
    )

    # Personel Ekle
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'adSoyad', 'password1', 'password2'),
        }),
        ('Groups', {'fields': ('groups',)}),
        ('Permissions', {'fields': ('user_permissions',)}),
    )

    ordering = ('email',)
    filter_horizontal = ()
    list_filter = ()

and the settings.py

AUTH_USER_MODEL = ‘m_auth.Account’ # app_name.model_name