如何在 django 中使用 OneToOneFeild 扩展 AbstractBaseUser
how to extend AbstractBaseUser with OneToOneFeild in django
我创建了 AbstractBaseUser 模型和一个 BaseManager。
下面给出model.py
GENDER_CHOICES = (('M', 'Male'),('F', 'Female'))
class AccountManager(BaseUserManager):
def create_user(self,email,username,phone,gender,password=None,**extrafields):
if not email:
raise ValueError("email is needed")
if not username:
raise ValueError("uname is needed")
if not phone:
raise ValueError("Phone is needed")
if not gender:
raise ValueError("gender is needed")
user= self.model(
email=self.normalize_email(email),
username=username,
phone=phone,
gender=gender,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email,username,phone,gender,password,**extrafields):
user=self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
phone=phone,
gender=gender,
)
user.is_admin=True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
ACCTYPE = (
('Student', 'Student'),
('Staff', 'Staff')
)
email=models.EmailField(verbose_name='E-mail', max_length=30, unique=True)
username=models.CharField(verbose_name='Username', max_length=30, unique=True)
last_login=models.DateTimeField(verbose_name='Last Login', auto_now=True)
phone=models.CharField(verbose_name='Phone', max_length=50)
gender= models.CharField(choices=GENDER_CHOICES, max_length=128)
acctype = models.CharField(max_length=16, choices=ACCTYPE)
is_admin=models.BooleanField(default=False)
is_active=models.BooleanField(default=True)
is_staff=models.BooleanField(default=False)
is_superuser=models.BooleanField(default=False)
USERNAME_FIELD ='username'
REQUIRED_FIELDS=['email','phone','gender']
objects=AccountManager()
def __str__(self):
return self.username
def has_perm(self,perm,obj=None):
return self.is_admin
def has_module_perms(self, app_lebel):
return True
And I am also tried to extend this user model Into StudentAccnt and StaffAccnt.
class StudentAccnt(models.Model):
user=models.OneToOneField(Account,on_delete=models.CASCADE)
reg_number=models.CharField(verbose_name='Reg NO', max_length=10,unique=True)
class StaffAccnt(models.Model):
user=models.OneToOneField(Account,on_delete=models.CASCADE)
id_number=models.CharField(verbose_name='Id NO', max_length=10,unique=True)
I want to create user using UserRegistrarionForm and add to StudentAccnt and StaffAccnt tables by checking acctype.
如何做到这一点??
终于找到解决办法了
it can be created using signals
When I create views for this custom user registration form, it simultaneously creates a corresponding instance.
我们需要导入这些
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db import models
add this at end of the view
@receiver(post_save,sender=Account)
def create_usersaccnt(sender,instance,created,**kwrags):
if created and (instance.acctype=='Student'):
StudentAccnt.objects.create(user=instance)
elif created and (instance.acctype=='Staff'):
StaffAccnt.objects.create(user=instance)
@receiver(post_save,sender=Account)
def save_usersaccnt(sender,instance,created,**kwrags):
if instance.acctype=='Student':
instance.studentaccnt.save()
elif instance.acctype=='Staff':
instance.staffaccnt.save()
you can also specify it through additional python file called signals.py
我创建了 AbstractBaseUser 模型和一个 BaseManager。
下面给出model.py
GENDER_CHOICES = (('M', 'Male'),('F', 'Female'))
class AccountManager(BaseUserManager):
def create_user(self,email,username,phone,gender,password=None,**extrafields):
if not email:
raise ValueError("email is needed")
if not username:
raise ValueError("uname is needed")
if not phone:
raise ValueError("Phone is needed")
if not gender:
raise ValueError("gender is needed")
user= self.model(
email=self.normalize_email(email),
username=username,
phone=phone,
gender=gender,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email,username,phone,gender,password,**extrafields):
user=self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
phone=phone,
gender=gender,
)
user.is_admin=True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
ACCTYPE = (
('Student', 'Student'),
('Staff', 'Staff')
)
email=models.EmailField(verbose_name='E-mail', max_length=30, unique=True)
username=models.CharField(verbose_name='Username', max_length=30, unique=True)
last_login=models.DateTimeField(verbose_name='Last Login', auto_now=True)
phone=models.CharField(verbose_name='Phone', max_length=50)
gender= models.CharField(choices=GENDER_CHOICES, max_length=128)
acctype = models.CharField(max_length=16, choices=ACCTYPE)
is_admin=models.BooleanField(default=False)
is_active=models.BooleanField(default=True)
is_staff=models.BooleanField(default=False)
is_superuser=models.BooleanField(default=False)
USERNAME_FIELD ='username'
REQUIRED_FIELDS=['email','phone','gender']
objects=AccountManager()
def __str__(self):
return self.username
def has_perm(self,perm,obj=None):
return self.is_admin
def has_module_perms(self, app_lebel):
return True
And I am also tried to extend this user model Into StudentAccnt and StaffAccnt.
class StudentAccnt(models.Model):
user=models.OneToOneField(Account,on_delete=models.CASCADE)
reg_number=models.CharField(verbose_name='Reg NO', max_length=10,unique=True)
class StaffAccnt(models.Model):
user=models.OneToOneField(Account,on_delete=models.CASCADE)
id_number=models.CharField(verbose_name='Id NO', max_length=10,unique=True)
I want to create user using UserRegistrarionForm and add to StudentAccnt and StaffAccnt tables by checking acctype.
如何做到这一点??
终于找到解决办法了
it can be created using signals
When I create views for this custom user registration form, it simultaneously creates a corresponding instance.
我们需要导入这些
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.db import models
add this at end of the view
@receiver(post_save,sender=Account)
def create_usersaccnt(sender,instance,created,**kwrags):
if created and (instance.acctype=='Student'):
StudentAccnt.objects.create(user=instance)
elif created and (instance.acctype=='Staff'):
StaffAccnt.objects.create(user=instance)
@receiver(post_save,sender=Account)
def save_usersaccnt(sender,instance,created,**kwrags):
if instance.acctype=='Student':
instance.studentaccnt.save()
elif instance.acctype=='Staff':
instance.staffaccnt.save()
you can also specify it through additional python file called signals.py