反转唯一的通用外键(并返回对象而不是相关的管理器)

Tim*_*ony 13 django

我有一个具有唯一通用外键关系的模型:

class Contact(models.Model):
    ...
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()

    class Meta:
         unique_together = ('content_type', 'object_id',)
Run Code Online (Sandbox Code Playgroud)

意思是一个Contact只能属于一个对象.通常,当我想扭转我能做的关系时

class Person(models.Model):
    ...
    contacts = generic.GenericRelation(Contact)
Run Code Online (Sandbox Code Playgroud)

并且召唤person.contacts.all()将给我所有的对象.因为Contact在我的情况下只会有一个返回,有没有更好的方法来反向访问这个对象?

我可以写,person.contact.all()[0]但必须有一个更清洁的方法

Tim*_*ony 12

好吧,看看Chris的评论中的问题有帮助,我写了一个mixin来使用快速查找返回对象(应该缓存):

class ContactMixin(object):
    @property
    def contactcard(self):
        ctype = ContentType.objects.get_for_model(self.__class__)
        try:
            contact = Contact.objects.get(content_type__pk = ctype.id, object_id=self.id)
        except Contact.DoesNotExist:
            return None 
        return contact
Run Code Online (Sandbox Code Playgroud)

和人:

 class Person(ContactMixin, models.Model):
     ...
Run Code Online (Sandbox Code Playgroud)

现在我可以打电话了

myperson.contactcard.phone_number 
Run Code Online (Sandbox Code Playgroud)

我不会接受,因为可能还有其他建议

  • 通常很好的做法是指定您期望的异常(在这种情况下会出现例证和多个对象).这样你就不会意外地隐藏其他你可能想要冒泡的异常 (2认同)

sec*_*ond 5

如果一个查询集只包含一个你可以做的元素qs.get(),或者你的情况

person.contact.get()
Run Code Online (Sandbox Code Playgroud)

(您可能仍需要捕获DoesNotExists异常)