Специальная загрузка связанного множества полей в запросе - PullRequest
0 голосов
/ 06 июня 2018

Я использую промежуточную модель с дополнительными полями для отношений «многие ко многим», как это:

class A(models.Model):
    name = models.CharField(max_length=128)

class B(models.Model):
    name = models.CharField(max_length=128)
    a = models.ManyToManyField(A, through='AB')

class AB(models.Model):
    a = models.ForeignKey(A, on_delete=models.CASCADE)
    b = models.ForeignKey(B, on_delete=models.CASCADE)
    number = models.IntegerField(default=0)
    date = models.DateTimeField()

По умолчанию AB.date равно NULL в базе данных.

Я получаювсе мои B экземпляры с чем-то вроде этого B.objects.all().

Тогда для каждого экземпляра B я могу получить набор AB, подобный этому, b_instance.ab_set.all().

Как загрузить только ab_set элементов, где date равно нулю?

В SQL это выглядело бы так:

SELECT * FROM B
INNER JOIN AB ON AB.id = B.ab_id AND AB.date IS NULL

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Проведя некоторые исследования по моей проблеме, я наконец нашел что-то, что могло бы решить проблему.

Я использовал Model method для фильтрации своего набора объектов:

class B(models.Model):
    ...
    def get_ab_with_null_date(self):
        return self.ab_set.filter(date__isnull=True)

Итак, яможно отфильтровать ab_set в моем шаблоне так:

{% for b in list_of_B %}
    {% for ab in b.get_ab_with_null_date %}
        ...
    {% endfor %}
{% endfor %}

Как вы думаете, есть более эффективный способ сделать это?

Кроме того, я виделчто-то о переопределении Manager , например:

b = B.objects.get(...)
b.custom_manager.get_ab_with_null_date() # return filtered ab_set with null date

Поскольку я не манипулирую своим ab_set непосредственно в представлении, я думаю, что это не очень полезно для моего случая.

0 голосов
/ 06 июня 2018

Вы можете выполнить фильтр с помощью __isnull [doc] поиска поля для этого, например:

b_instance.ab_set.filter(<b>date__isnull=True</b>)

Таким образом, мы .filter(..) на съемочной площадке, указав, что поле date isnull.

В качестве альтернативы, если вы, например, хотите запросить также и не-1016 * date, выможно фильтровать с date=None:

b_instance.ab_set.filter(<b>date=None</b>)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...