Набор запросов Django для соответствия всем связанным объектам - PullRequest
4 голосов
/ 22 июля 2011

Допустим, у меня есть ForeignKey от кокоса до ласточки (то есть ласточка несла много кокосовых орехов, но каждый кокос был перенесен только одной ласточкой).Теперь предположим, что у меня есть ForeignKey от husk_segment в Coconut.

Теперь у меня есть список husk_segment, и я хочу выяснить, все ли из них были перенесены определенной ласточкой.

У меня может быть файл swallow.objects.filter (coconuts_carried__husk_sements__in = husk_segment_list), чтобы показать, что эта ласточка захватила хотя бы один сегмент шелухи в списке.Теперь, как я могу показать, что каждый сегмент шелухи, который когда-либо носил ласточка, находится в этом списке?

Ответы [ 3 ]

2 голосов
/ 22 июля 2011

У меня может быть swallow.objects.filter (coconuts_carried__husk_sements__in = husk_segment_list), чтобы показать, что эта ласточка захватила хотя бы один сегмент шелухи в списке.

Нет, это неправильно,это дает вам список ласточек , которые содержат по крайней мере один сегмент шелухи из * husk_segment_list *.

Если я правильно понял, мы говорим о проверке конкретной ласточки.

Итак, исходя из вашего описания, я думаю, что ваши модели выглядят примерно так:

class Swallow(models.Model):
    name = models.CharField(max_length=100)


class Coconut(models.Model):
    swallow = models.ForeignKey(Swallow, related_name='coconuts_carried')



class HuskSegment(models.Model):
    coconut = models.ForeignKey(Coconut, related_name='husk_segments')

Если у вас уже есть список сегментов шелухи, вам нужно снова проверить сегменты ласточек, вам нет необходимостиразрешить это в запросе.Получите сегменты ласточек и проверьте, является ли это надмножеством вашего списка сегментов шелухи.

Итак, у нас есть:

#husk_segment_list = [<object: HuskSegment>, <object: HuskSegment>, <object: HuskSegment>...]
husk_segments_set = set((husk.pk for husk in husk_segment_list))

whitey = Swallow.object.get(name='Neochelidon tibialis')
wh_segments_set = set((value[0] for value in HuskSegment.objects.filter(coconut__in=whitey.coconuts_carried.all()).values_list('id')))

whitey_has_carried_all = wh_segments_set.issuperset(husk_segments_set)
2 голосов
/ 22 июля 2011

См. документы по запросам, охватывающим многозначные отношения - вы должны фильтровать вызовы.

Простой путь - что-то вроде

queryset = Swallow.objects.all()
for coconut in coconuts:
    queryset = queryset.filter(coconuts_carried=coconut)

Причудливый способ сделать это в одну строку, используя reduce, будет

reduce(lambda q, c: q.filter(coconuts_carried=c), coconuts, Swallow.objects.all())
0 голосов
/ 22 июля 2011

Если я правильно понял ваш измененный вопрос, вы сможете сравнить coconut_carried_set ласточки со списком перенесенных кокосовых орехов.

см. документы

Я не совсем уверен, что это то, что вы хотите - я думаю, это зависит от того, знаете ли вы, какую ласточку вы хотите проверить заранее или хотите ли вы проверить ее на предмет всех ласточек - в этом случае может быть лучше решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...