覆盖save()方法

时间:2015-12-30 22:02:50

标签: python django django-admin

我在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)? / p>

我之前向所有人道歉,如果我的问题不适合或没有使用stackoverflow哲学或我的问题。

它的原因在于我想要提供所有细节以获得答案

任何方向我将不胜感激并将不胜感激

2 个答案:

答案 0 :(得分:2)

如果用户没有医疗,您需要在保存方法中执行某些操作;你仍然需要实际保存对象。

固定的实施方式是:

def save(self, *args, **kwargs):
    user = super(User, self).save(self, *args, **kwargs)
    if self.is_medical:
        MedicalProfile(user=self).save()

答案 1 :(得分:0)

位于class User的{​​{1}}覆盖了保存方法,保持原样:

userprofile/models.py

save()方法让我可以使用所有可能的配置文件组合保存用户。

但是,有更好的方法吗?