Django 获取泛型外键的属性

Django 获取泛型外键的属性,django,generics,django-contenttypes,Django,Generics,Django Contenttypes,我仍在努力研究Django中的通用外键,所以到目前为止我所想到的是非常基本的。我正在尝试创建一个NotificationRecipient,它具有我已经创建的两个不同模型的通用外键。这些通知收件人可以是客户端或帐户。我可能会决定添加更多新型号的收件人 我想在NotificationRecipient中创建一个get_email方法,检查收件人是联系人、客户还是帐户。然后,根据它是哪个模型,它会提取不同的属性 我现有的模型看起来有点像这样: class Client(models.Model):

我仍在努力研究Django中的通用外键,所以到目前为止我所想到的是非常基本的。我正在尝试创建一个
NotificationRecipient
,它具有我已经创建的两个不同模型的通用外键。这些通知收件人可以是
客户端
帐户
。我可能会决定添加更多新型号的收件人

我想在NotificationRecipient中创建一个
get_email
方法,检查收件人是联系人、客户还是帐户。然后,根据它是哪个模型,它会提取不同的属性

我现有的模型看起来有点像这样:

class Client(models.Model):
    primary_email = models.EmailField(blank=True)
    ...

class Account(AbstractNamedUser):
    email = models.EmailField(blank=True)
    ...
根据型号,尝试获取电子邮件:

class NotificationRecipient(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    def get_email_addr(self):
        ''' Gets the model, then pulls the email address. '''
        # Get the model
        # if client:
            # return primary_email
        # elif account:
            # return email

我该怎么做呢?

您可以检查
内容\u类型
字段以确定对象的类型


<>但不检查类型,您可以考虑在所有返回相关属性的目标模型上定义一个属性。

< P>最好在您的目标模型上定义一个方法,而不是在NoToReCaseAccess模型中建立所有的业务逻辑。< /P> 逻辑是NotificationRecipient模型只需要知道它需要一个电子邮件地址

class Client(...):
    def get_email_addr(self):
        return primary_email

class Account(...):
    def get_email_addr(self):
        return email

class NotificationRecipient(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    def get_email_addr(self):

        try:
            email = self.content_object.get_email_addr()

        # if you want to enforce the attribute
        except AttributeError:
            raise ImproperlyConfigured('Model requires an email address')

        # if you need a default
        if not email:
            return 'default@email.com'

        return email