Как я могу запросить модель, если есть экземпляр подкласса? - PullRequest
2 голосов
/ 26 февраля 2009

У меня есть две простые модели, A и B:

from django.db import models

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

class B(A):
  age = models.IntegerField()

Теперь, как я могу запросить все экземпляры A, у которых нет экземпляра B?

Единственный способ, который я нашел, требует наличия в каждом подклассе явно уникального поля, которое НЕ ПУСТО, чтобы я мог, например, сделать A.objects.filter (b__this_is_a_b = None), чтобы получить экземпляры, которые не являются также экземплярами B , Я ищу способ сделать это без добавления явного глупого флага, подобного этому.

Я также не хочу запрашивать все объекты и затем фильтровать их в Python. Я хочу, чтобы БД делала это для меня, что в общем-то похоже на SELECT * FROM A WHERE A.id in (SELECT id from B)

Ответы [ 3 ]

2 голосов
/ 31 мая 2012

Начиная с некоторой версии django или python, это также работает:

A.Objects.all().filter(b__isnull=True)

потому что, если a является объектом A, a.b дает подкласс B для a, когда он существует

Я знаю, что это старый вопрос, но мой ответ может помочь новым поисковикам на эту тему.

см. Также:

наследование нескольких таблиц

И один из моих собственных вопросов по этому поводу: перевод суперкласса в подкласс

1 голос
/ 26 февраля 2009

Я не уверен, что это можно сделать исключительно в БД с помощью Django ORM, в одном запросе. Вот лучшее, что я смог сделать:

A.objects.exclude(id__in=[r[0] for r in B.objects.values_list("a_ptr_id")])

Это 2 запроса к БД, которые лучше всего работают с упрощенным наследованием. graph - для каждого подкласса A потребуется новый запрос к базе данных.


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

A.objects.exclude(b__age__isnull=True).exclude(b__age_isnull=False)

Нет способа заставить Джанго выполнить соединение, не ссылаясь на поле на б. Но с этими последовательными .exclude() s вы делаете any A с подклассом B соответствует одному или другому исключению. Все, что вам осталось, это А без подкласса B.

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

0 голосов
/ 26 февраля 2009

Я не работаю с django, но, похоже, вам нужен встроенный метод python isinstance (obj, type).

Edit:
Будет ли работать A.objects.exclude (id__exact = B__id)?

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