重写save()方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重写save()方法相关的知识,希望对你有一定的参考价值。
我在Django中有一个自定义用户模式,用于处理角色或用户类型,创建一个名为userprofile的应用程序,它将设置或将设置我的自定义用户模型。
在我的settings.py中,我有以下配置:
INSTALLED_APPS = [
...
'userprofile',
]
#Custom model Users
AUTH_USER_MODEL = 'userprofile.User'
我自定义继承AbstractUser类的User类(userprofile / models.py),以便根据我的要求向我的User模型添加一些字段。
我还为角色/配置文件用户(MedicalProfile, PatientProfile, PhysiotherapistProfile
)创建了这些具有自己的字段或属性的另一个模型
另外MedicalProfile, PatientProfile, PhysiotherapistProfile
与我的自定义模型/类User
有一个OneToOneField关系,所以:
from __future__ import unicode_literals
from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save
class User(AbstractUser):
is_medical = models.BooleanField(default=False)
is_physiotherapist = models.BooleanField(default=False)
is_patient = models.BooleanField(default=False)
slug = models.SlugField(max_length=100, blank=True)
photo = models.ImageField(upload_to='avatars', null = True, blank = True)
# Overriding the save method
def save(self, *args, **kwargs):
if self.is_medical:
profile = MedicalProfile(user=self)
super(User, self).save(self, *args, **kwargs)
profile.save()
# We get the profiles user according with their type
def get_medical_profile(self):
medical_profile = None
if hasattr(self, 'medicalprofile'):
medical_profile=self.medicalprofile
return medical_profile
def get_patient_profile(self):
patient_profile = None
if hasattr(self, 'patientprofile'):
patient_profile = self.patientprofile
return patient_profile
def get_physiotherapist_profile(self):
physiotherapist_profile = None
if hasattr(self, 'physiotherapistprofile'):
physiotherapist_profile = self.physiotherapistprofile
return physiotherapist_profile
class Meta:
db_table = 'auth_user'
class MedicalProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
class PatientProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
class PhysiotherapistProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
我的问题
我想把我的问题集中在覆盖过程save()
方法上:
def save(self, *args, **kwargs):
if self.is_medical:
profile = MedicalProfile(user=self)
super(User, self).save(self, *args, **kwargs)
profile.save()
我希望,每创建一个用户,根据他们的字段选中(is_medical,is_patient,is_physiotherapist)自动创建他们的个人资料(MedicalProfile,PatientProfile,PhysiotherapistProfile)
我不方便的是我的覆盖过程如下:
- 当我通过django admin创建用户时,我收到此错误
我不知道它,关于将用户PK设置为无的原因...
我可以有什么替代方案来解决这种情况,当我创建用户时,他们的个人资料实例会被保存(MedicalProfile,PhysiotherapistProfile,PatientProfile),具体取决于我选择的属性checkbo / field(is_medical,is_physiotherapist,is_patient)?
我之前向所有人道歉,如果我的问题不适合或没有使用stackoverflow哲学或我的问题。
这是因为我想要提供所有细节以获得答案
任何方向我将不胜感激,并将不胜感激
如果用户没有医疗,您需要在保存方法中执行某些操作;你仍然需要实际保存对象。
固定的实施将是:
def save(self, *args, **kwargs):
user = super(User, self).save(self, *args, **kwargs)
if self.is_medical:
MedicalProfile(user=self).save()
我位于class User
的userprofile/models.py
覆盖了保存方法,保持如此:
class User(AbstractUser):
is_medical = models.BooleanField(default=False)
is_physiotherapist = models.BooleanField(default=False)
is_patient = models.BooleanField(default=False)
slug = models.SlugField(max_length=100, blank=True)
photo = models.ImageField(upload_to='avatars', null = True, blank = True)
def save(self, *args, **kwargs):
user = super(User, self).save( *args, **kwargs)
# Creating and user with medical, patient and physiotherapist profiles
if self.is_medical and not MedicalProfile.objects.filter(user=self).exists()
and self.is_patient and not PatientProfile.objects.filter(user=self).exists()
and self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists():
medical_profile=MedicalProfile(user=self).save()
patient_profile=PatientProfile(user=self).save()
physiotherapist_profile=PhysiotherapistProfile(user=self).save()
#profile.save()
# Creating and user with medical and patient profiles
elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists()
and self.is_patient and not PatientProfile.objects.filter(user=self).exists():
medical_profile=MedicalProfile(user=self).save()
patient_profile=PatientProfile(user=self).save()
# Creating and user with medical and physiotherapist profiles
elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists()
and self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists():
medical_profile=MedicalProfile(user=self).save()
physiotherapist_profile=PhysiotherapistProfile(user=self).save()
# Creating and user with physiotherapist and patient profiles
elif self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists()
and self.is_patient and not PatientProfile.objects.filter(user=self).exists():
physiotherapist_profile = PhysiotherapistProfile(user=self).save()
patient_profile = PatientProfile(user=self).save()
# Creating and user with medical profile
elif self.is_medical and not MedicalProfile.objects.filter(user=self).exists():
profile = MedicalProfile(user=self)
profile.save()
# Creating and user with patient profile
elif self.is_patient and not PatientProfile.objects.filter(user=self).exists():
profile = PatientProfile(user=self)
profile.save()
# Creating and user with physiotherapist profiles
elif self.is_physiotherapist and not PhysiotherapistProfile.objects.filter(user=self).exists():
profile = PhysiotherapistProfile(user=self)
profile.save()
# We get the profiles user according with their type
def get_medical_profile(self):
medical_profile = None
if hasattr(self, 'medicalprofile'):
medical_profile=self.medicalprofile
return medical_profile
def get_patient_profile(self):
patient_profile = None
if hasattr(self, 'patientprofile'):
patient_profile = self.patientprofile
return patient_profile
def get_physiotherapist_profile(self):
physiotherapist_profile = None
if hasattr(self, 'physiotherapistprofile'):
physiotherapist_profile = self.physiotherapistprofile
return physiotherapist_profile
# We redefine the attributes (create db_table attribute) in class Meta to say to Django
# that users will save in the same table that the Django default user model
# https://github.com/django/django/blob/master/django/contrib/auth/models.py#L343
class Meta:
db_table = 'auth_user'
class MedicalProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
class PatientProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
class PhysiotherapistProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
#active = models.BooleanField(default=True)
name = models.CharField(max_length=64)
# Enter the username as slug field
@receiver(post_save, sender = settings.AUTH_USER_MODEL)
def post_save_user(sender, instance, **kwargs):
slug = slugify(instance.username)
User.objects.filter(pk=instance.pk).update(slug=slug)
save()方法让我可以使用所有可能的配置文件组合来保存用户。
但是,有更好的方法吗?
以上是关于重写save()方法的主要内容,如果未能解决你的问题,请参考以下文章