Фильтр django queryset: Запрашивает объекты с двумя или более объектами, связанными с обратными, с определенным идентичным значением поля - PullRequest
0 голосов
/ 09 февраля 2020

Предположим, у нас есть две модели, подобные этой:

from django.db import models

ModelA(models.Model):
    ...

ModelB(models.Model):
    a = models.ForeignKey(ModelA, ..., related_name='b_models')
    some_field = models.CharField(...)
    other_field = ...
    ...

Что мне делать, если я хочу получить ModelA набор запросов, содержащий только тех объектов, которые имеют два или более b_models указывают на то, что имеют одинаковое значение для some_field?

Рассмотрим этот пример настройки:

a1, a2 = ModelA.objects.create(...), ModelA.objects.create(...)

b1 = ModelB.objects.create(a=a1, some_field="foo" ...)
b2 = ModelB.objects.create(a=a1, some_field="foo" ...)
b3 = ModelB.objects.create(a=a1, some_field="bar" ...)
b4 = ModelB.objects.create(a=a2, some_field="baz" ...)
b5 = ModelB.objects.create(a=a2, some_field="foo" ...)

В этом Например, набор запросов должен содержать объект a1, поскольку оба объекта b1 и b2 относятся к нему и оба имеют значение foo в some_field. (И не содержит a2, поскольку оно не удовлетворяет второму требованию.)

Я знаю, что могу использовать .annotate(models.Count('b_models')), а затем .filter(b_models__count__gte=2), чтобы получить эти экземпляры ModelA с двумя или более обратными отношениями из ModelB. Но в этом примере это вернуло бы и a1 и a2. Как мне удовлетворить второе требование и отфильтровать набор запросов дальше?

(или есть ли общий подход еще лучше, чем мое предложение annotate?)

РЕДАКТИРОВАТЬ: Чтобы уточнить, мне не нужно знать , что будет значение специфика c из some_field. Второе требование состоит в том, что ModelB экземпляры идентичны по значению для some_field. Поэтому, если бы я добавил

b6 = ModelB.objects.create(a=a2, some_field="baz" ...)

, запрос должен вернуть и a1, и a2.

1 Ответ

0 голосов
/ 09 февраля 2020

Вы можете попробовать добавить другой фильтр, например, .filter(b_models__count__gte=2, b_models__some_field="foo")

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