Подтвердить что ты не робот

Реверсирование уникального общего внешнего ключа (и возвращение объекта в отличие от связанного менеджера)

У меня есть модель, которая имеет уникальную общую взаимосвязь внешнего ключа:

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',)

означает, что a Contact может принадлежать только одному объекту. Обычно, когда я хочу изменить отношения, я могу сделать

class Person(models.Model):
    ...
    contacts = generic.GenericRelation(Contact)

и вызов person.contacts.all() даст мне все объекты. Поскольку в моей ситуации когда-либо будет возвращен только один Contact, есть ли лучший способ доступа к этому объекту в обратном порядке?

p.s. Я мог написать person.contact.all()[0], но должен быть более чистый подход

4b9b3361

Ответ 1

Ну, посмотрев на вопрос в комментарии Криса, помог, и я написал 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

и Person:

 class Person(ContactMixin, models.Model):
     ...

теперь я могу просто позвонить

myperson.contactcard.phone_number 

Я пока не соглашусь, так как могут быть и другие предложения

Ответ 2

если набор запросов содержит ровно один элемент, который вы можете сделать qs.get(), или в вашем случае

person.contact.get()

(вам все равно нужно поймать исключение DoesNotExists)