Django注册两种不同类型的不同字段的用户
Django Registering two different types of users with different fields
我想创建两个用户:patient
和 doctor
。两个用户将共享一些标准字段,如 first_name
、last_name
等。但是,他们应该有不同的字段。例如,只有 doctor
才会有像 expertise
和 days_available
.
这样的字段
我查看了一个类似的问题,但它并没有完全解决我的具体需求。我不一定需要自定义 permissions/authentication,因为我只需要为每个用户提供单独的字段。我已经尝试了最后一种方法,即扩展用户模型,但是当我创建用户时,它并没有 linked 到 patient/doctor。我必须手动创建一个医生并将其 link 提供给用户。
doctor/patient如何在创建用户时自动创建?
class User(AbstractUser):
is_doctor = models.BooleanField(default=False)
is_patient = models.BooleanField(default=False)
class Patient(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_patient = True
pid = models.AutoField(unique=True, primary_key=True) #patient identification
class Doctor(models.Model):
upin = models.AutoField(primary_key=True) #unique physician identification number
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_doctor = True
expertise = models.CharField(max_length=20)
days_available = models.DateTimeField(null=True)
您的 User
型号默认 objects
设置为 auth.models.UserManager
。您应该覆盖该方法:
class User(AbstractUser):
... # fields
objects = MedicalUserManager()
class MedicalUserManager(models.UserManager):
def create_user(self, username, email=None, password=None, **extra_fields):
# pop all fields you want to use for `Doctor` or `Patient` from `extra_fields`
doctor_pin = extra_fields.pop('doctor_pin', None)
pid = extra_fields.pop('pid', None)
user = super().create_user(username, email, password, **extra_fields)
if doctor_pin:
doctor = Doctor.objects.create(user=user, upin=doctor_pin)
user.is_doctor = True # not needed if `is_doctor` is in `extra_fields` because it would have been saved when creating the `User`
user.save()
elif pid:
patient = Patient.objects.create(user=user, pid=pid)
user.is_patient = True
user.save()
return user
查看this blog post--特别是第二个选项:"Extending the User Model using a One-to-One link."作者建议在用户对象为created/updated时使用信号自动执行操作。也许尝试这样的事情:
class User(AbstractUser):
is_doctor = models.BooleanField(default=False)
is_patient = models.BooleanField(default=False)
class Patient(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_patient = True
pid = models.AutoField(unique=True, primary_key=True) #patient identification
class Doctor(models.Model):
upin = models.AutoField(primary_key=True) #unique physician identification number
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_doctor = True
expertise = models.CharField(max_length=20)
days_available = models.DateTimeField(null=True)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
if instance.is_patient:
Patient.objects.create(user=instance)
elif instance.is_doctor:
Doctor.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
if instance.is_patient:
instance.patient.save()
elif instance.is_doctor:
instance.doctor.save()
我想创建两个用户:patient
和 doctor
。两个用户将共享一些标准字段,如 first_name
、last_name
等。但是,他们应该有不同的字段。例如,只有 doctor
才会有像 expertise
和 days_available
.
我查看了一个类似的问题,但它并没有完全解决我的具体需求。我不一定需要自定义 permissions/authentication,因为我只需要为每个用户提供单独的字段。我已经尝试了最后一种方法,即扩展用户模型,但是当我创建用户时,它并没有 linked 到 patient/doctor。我必须手动创建一个医生并将其 link 提供给用户。 doctor/patient如何在创建用户时自动创建?
class User(AbstractUser):
is_doctor = models.BooleanField(default=False)
is_patient = models.BooleanField(default=False)
class Patient(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_patient = True
pid = models.AutoField(unique=True, primary_key=True) #patient identification
class Doctor(models.Model):
upin = models.AutoField(primary_key=True) #unique physician identification number
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_doctor = True
expertise = models.CharField(max_length=20)
days_available = models.DateTimeField(null=True)
您的 User
型号默认 objects
设置为 auth.models.UserManager
。您应该覆盖该方法:
class User(AbstractUser):
... # fields
objects = MedicalUserManager()
class MedicalUserManager(models.UserManager):
def create_user(self, username, email=None, password=None, **extra_fields):
# pop all fields you want to use for `Doctor` or `Patient` from `extra_fields`
doctor_pin = extra_fields.pop('doctor_pin', None)
pid = extra_fields.pop('pid', None)
user = super().create_user(username, email, password, **extra_fields)
if doctor_pin:
doctor = Doctor.objects.create(user=user, upin=doctor_pin)
user.is_doctor = True # not needed if `is_doctor` is in `extra_fields` because it would have been saved when creating the `User`
user.save()
elif pid:
patient = Patient.objects.create(user=user, pid=pid)
user.is_patient = True
user.save()
return user
查看this blog post--特别是第二个选项:"Extending the User Model using a One-to-One link."作者建议在用户对象为created/updated时使用信号自动执行操作。也许尝试这样的事情:
class User(AbstractUser):
is_doctor = models.BooleanField(default=False)
is_patient = models.BooleanField(default=False)
class Patient(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_patient = True
pid = models.AutoField(unique=True, primary_key=True) #patient identification
class Doctor(models.Model):
upin = models.AutoField(primary_key=True) #unique physician identification number
user = models.OneToOneField(User, on_delete=models.CASCADE)
user.is_doctor = True
expertise = models.CharField(max_length=20)
days_available = models.DateTimeField(null=True)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
if instance.is_patient:
Patient.objects.create(user=instance)
elif instance.is_doctor:
Doctor.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
if instance.is_patient:
instance.patient.save()
elif instance.is_doctor:
instance.doctor.save()