#django #django-models #orm #django-templates #django-orm
Вопрос:
Модели:
class House(Model)
class Flat(Model):
house = ForeignKey(House, related_name="houses")
owner = ForeignKey(User)
class User(Model)
набор запросов:
queryset = User.objects.prefetch_related(
Prefetch("flats", queryset=Flat.objects.select_related("houses"))
А потом квартиры:
{% for flat in user.flats.all %}
<p>№ {{ flat.number }}, {{ flat.house.name }}</p>
{% endfor %}
Все в порядке. Но для домов мне нужны только уникальные
{% for flat in user.flats.all %}
<p>House {{ flat.house.name }}</p>
{% endfor %}
Но этот шаблон дает мне ВСЕ дома с дубликатами.
Как я могу избежать дубликатов, каких-либо идей? Я попробовал .distinct (), но это не сработало, похоже, я неправильно использую distinct() или т. Д.
Ответ №1:
Похоже, у вас могут оказаться дубликаты домов, если пользователь принадлежит к owner
нескольким flat
s, которые все находятся в одном и том же house
. Чтобы получить все дома, с которыми пользователь связан через Flat
s, вы можете использовать другой запрос, начиная с House
, чтобы вы могли использовать distinct
:
distinct_houses = House.objects.filter(flats__owner=user).distinct()
Вышесказанное возвращает один объект дома для каждой квартиры, владельцем которой является пользователь, и гарантирует, что у вас нет дубликатов. (Обратите внимание , что выше предполагается related_name
, что значение изменено на flats
для house = ForeignKey(House, related_name="flats")
, так как «дома» в качестве связанного имени похоже на опечатку, связанную с Flat
моделью.)
В качестве альтернативы вы могли бы сделать что-то в памяти на Python, если вам все еще нужно знать все Flat
s через ваш оригинал queryset = User.objects.prefetch_related(...)
и вам не нужен дополнительный запрос. Нравится:
distinct_houses = {flat.house for flat in user.flats.all()}
Примечание: похоже, у вас есть опечатка в необходимости использования Flat.objects.select_related('house')
, а не Flat.objects.select_related('houses')
на основе имени поля внешнего ключа house
.
Комментарии:
1. Но проблема в том, что мне нужен пользовательский запрос со всеми квартирами и уникальными домами для каждого пользователя.
Ответ №2:
Найдено только решение с фильтрами шаблонов. Набор запросов:
queryset = User.objects.filter(status="ACTIVE").prefetch_related(
Prefetch("flats", queryset=Flat.objects.select_related("house"))
)
С помощью этого я могу получить все квартиры для каждого пользователя:
{% for user in object_list %}
{% for flat in user.flats.all %}
{{ flat.number }}, {{ flat.house.name }}
{% endfor %}
{% endfor %}
И я использую фильтр шаблонов для получения уникальных домов.
{% for user in object_list %}
{% for flat in user.flats.all|get_unique_houses %}
{{ flat.house.name }}
{% endfor %}
{% endfor %}
# extra_tags.py
@register.filter(name="get_unique_houses")
def get_unique_houses(value):
return value.distinct('house')