Аннотировать обратный связанный объект через Django QuerySet - PullRequest
0 голосов
/ 23 апреля 2019

Ситуация

Предположим, у меня есть следующие модели:

class Garage(models.Model):
    width = ...
    height = ...

class Car(models.Model):
   garage = models.ForeignKey('Garage', on_delete=models.CASCADE)
   brand = ...

Теперь предположим, что мне нужно найти все гаражи с width > 30 и содержащие автомобили Toyota.

Тогда я могу сделать простой запрос, подобный этому:

results = Garage.objects.filter(width__gt=30, car__brand__icontains='Toyota')

Проблема

Показывая мои результаты, сгруппированные по гаражу, мне нужно выделить автомобили Toyota, например:

GARAGE A
Volvo C30
Toyota Prius <---highlight this
Saab 93

GARAGE B
Toyota Yaris <---highlight this

GARAGE C
Fiat 500
Toyota C-HR <---highlight this

Django annotate () не работает со связанными полями.

Любое умное решение?

N.B. Мне нужно выполнить запрос по модели гаража (не по автомобилю).

EDIT

Чтобы уточнить мой вопрос, у меня есть форма поиска в веб-интерфейсе. Пользователь может искать гаражные атрибуты и / или автомобильные атрибуты.

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

Учитывая приведенный выше пример (который является упрощенной версией), в моем шаблоне у меня есть что-то вроде этого:

{% for garage in results %}
     <div>
     Garage #{{garage.id}}: W {{garage.width}} x H {{garage.height}}
         <div>
         {% for car in results.car_set.all %}
             <span> {{car.brand}} {{car.model}} ... </span>
         {% endfor %}
         </div>
     </div>    

{% endfor %}

Все полностью работает. Но мне все еще нужно выделить интересующие автомобили (например, только автомобили «Тойота»).

Надеюсь, теперь мне ясно. Спасибо всем.

1 Ответ

0 голосов
/ 23 апреля 2019

Django annotate поддерживает расширение обратных отношений. Вам нужно знать правильное связанное имя для вашего отношения, я предлагаю вам использовать свойство related_name, чтобы определить, как обратный поиск должен называться следующим образом:

class Car(models.Model):
   garage = models.ForeignKey('Garage', on_delete=models.CASCADE, related_name='cars')
   brand = ...

Тогда ваш запрос должен быть

results = Garage.objects.filter(width__gt=30, cars__brand__icontains='Toyota')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...