Реверсирование уникального общего внешнего ключа (и возвращение объекта в отличие от связанного менеджера)
У меня есть модель, которая имеет уникальную общую взаимосвязь внешнего ключа:
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]
, но должен быть более чистый подход
Ответы
Ответ 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
)