向Django字段添加其他属性

2024-04-26 07:49:57 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑一下Django中的Family模型:

class Family(models.Model):
    EMPLOYEE = 'Employee'
    PARTNER = 'Partner'
    BIRTH_PARENT_CHOICES = (
       (EMPLOYEE, EMPLOYEE),
       (PARTNER, PARTNER),
    )
    employee_user = models.OneToOneField(User, blank=True, null=True, related_name='employee_family')
    partner_user = models.OneToOneField(User, blank=True, null=True, related_name='partner_family')
    employee_first_name = models.CharField(max_length=255, blank=True)
    employee_last_name = models.CharField(max_length=255, blank=True)
    employee_email = models.CharField(max_length=255, blank=True)
    employee_phone = models.CharField(max_length=255, blank=True)
    partner_first_name = models.CharField(max_length=255, blank=True)
    partner_last_name = models.CharField(max_length=255, blank=True)
    partner_email = models.CharField(max_length=255, blank=True)
    partner_phone = models.CharField(max_length=255, blank=True)
    point_of_contact = models.CharField(max_length=255, choices=BIRTH_PARENT_CHOICES)

一个Family由一个雇员和一个合作伙伴组成,这两个成员都有不同的属性(用户、名字、姓氏、电子邮件、电话)。还有一个point_of_contact字段,它是'Employee''Partner'。你知道吗

我想做的是,在familyFamily实例上,执行以下操作

family.point_of_contact.phone_number

如果family.point_of_contact == Family.EMPLOYEE则解析为family.employee_phone_number,否则解析为family.partner_phone_number,对于first_namelast_name等类似

然而,就我从https://docs.djangoproject.com/en/2.0/ref/models/fields/所知,不可能在Django字段上定义其他属性。我还有别的办法吗?你知道吗


Tags: ofnametruepartnermodelsemployeephonefamily
2条回答

Django没有提供这样做的方法,但是您可以使用一些简单的Python:

from types import SimpleNamespace

class Family(SimpleNamespace):
    EMPLOYEE = 'employee'
    PARTNER = 'partner'

    @property
    def contact(self):
        return SimpleNamespace(**{
            attr: getattr(self, '%s_%s' % (self.point_of_contact, attr))
            for attr in 'first_name last_name'.split()
        })

family = Family(
    employee_first_name='Kurt',
    employee_last_name='Peek',
    partner_first_name='Jane',
    partner_last_name='Doe',
    point_of_contact=Family.EMPLOYEE,
)

print(family.contact.first_name)
print(family.contact.last_name)

这里SimpleNamespace有两种用法:

  1. 作为Family的一个超类,要使这个示例易于测试,请跳过它并坚持使用models.Model。你知道吗
  2. contact属性中,保留该属性。你知道吗

不,为了做到这一点,您需要创建一个单独的模型Contact,并使用OneToOneField(如果每个族只能有一个联系人)从Family连接到它,或者如果每个族可以有多个联系人,则在Contact模型中使用ForeignKey。你知道吗

相关问题 更多 >