首页 文章

向Django字段添加其他属性

提问于
浏览
2

在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.EMPLOYEEfamily.partner_phone_number 否则将解析为 family.employee_phone_number ,对于 first_namelast_name 等也是如此 .

但是,据我所知,从https://docs.djangoproject.com/en/2.0/ref/models/fields/可以看出,无法在Django字段上定义其他属性 . 还有其他方法可以做到这一点吗?

2 回答

  • 1

    不,为了做到这一点,您需要创建一个单独的模型 Contact 并使用 OneToOneFieldFamily 加入到它,如果每个家庭只能有一个联系人,或者如果可能有超过 Contact 的模型中使用 ForeignKey 每个家庭一个联系人 .

  • 1

    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 有两种使用方式:

    • 作为 Family 的超类使这个例子易于测试 - 跳过它并坚持 models.Model .

    • contact 属性中,保留它 .

相关问题