models.py
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
"""Define a model manager for User model with no username field."""
def _create_user(self, email, password=None, **extra_fields):
"""Create and save 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_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password=None, **extra_fields):
"""Create and save a SuperUser with the given email and password."""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', 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(email, password, **extra_fields)
class CustomUser(AbstractUser):
is_customer = models.BooleanField('customer status', default=False)
is_vendor = models.BooleanField('vendor status', default=False)
class Customer(models.Model):
customeruser = models.OneToOneField(CustomUser, on_delete=models.CASCADE,
primary_key=True)
username = None
email = models.EmailField(_('email address'), unique=True)
firstname = models.CharField(max_length=200)
lastname = models.CharField(max_length=200)
mobileno = models.IntegerField(blank=True, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
class Vendor(models.Model):
vendoruser = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True)
username = None
email = models.EmailField(_('email address'), unique=True)
firstname = models.CharField(max_length=200)
lastname = models.CharField(max_length=200)
mobileno = models.IntegerField(blank=True, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
I am using the email field as main field instead of the username field to signup and login. also, in admin.py i used email as the main field. While attempting makemigrations showing error (django.core.exceptions.FieldError: Unknown field(s) (mobileno) specified for CustomUser)Is it the right way to approach?
can i use django default auth login,logout,password-reset functionalities for both of these user types?
Migration error... I would say you have mobileno
somewhere in admin.py
On CustomUser ModelAdmin class.
About User model. What you actually did is that you have still one user model(I think Django's auth doesn't support more) with some extra data for Customers and Vendors. So USERNAME_FIELD
, REQUIRED_FIELDS
etc. should be just on CustomUser
class and only fields specified for customers and vendors should be on these models.
so your models should look something like this:
class CustomUser(AbstractUser):
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
username = None
email = models.EmailField(_("email address"), unique=True)
mobileno = models.IntegerField(blank=True, null=True)
objects = CustomUserManager()
def is_customer(self):
return hasattr(self, "customer")
def is_vendor(self):
return hasattr(self, "vendor")
class Customer(models.Model):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE,
primary_key=True)
customer_number = models.CharField(max_length=32) # just some customer specific field
class Vendor(models.Model):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True)
vendor_number = models.CharField(max_length=32) # just some vendor specific field
And you can add create_customer
and create_vendor
methods to manager:
class CustomUserManager(BaseUserManager):
"""Define a model manager for User model with no username field."""
def _create_user(self, email, password=None, **extra_fields):
"""Create and save 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_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password=None, **extra_fields):
"""Create and save a SuperUser with the given email and password."""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', 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(email, password, **extra_fields)
def create_customer(self, email, password=None, customer_number, **extra_fields):
user = self.create_user(email, password, **extra_fields)
Customer.objects.create(user=user, customer_number=customer_number)
return user
def create_vendor(self, email, password=None, vendor_number, **extra_fields):
user = self.create_user(email, password, **extra_fields)
Vendor.objects.create(user=user, vendor_number=vendor_number)
return user
You can read about it in Django's docs https://docs.djangoproject.com/en/3.2/topics/auth/customizing/#extending-the-existing-user-model
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.