重写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创建用户时,我收到此错误

enter image description here

我不知道它,关于将用户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 Useruserprofile/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()方法的主要内容,如果未能解决你的问题,请参考以下文章

重写保存按钮save事件

odoo 怎么重写模块默认方法

推进学说代码片段

java 代码片段

多线程 Thread 线程同步 synchronized

canvas 中save和restore的用法