Как отобразить два QuerySets в одной таблице? - PullRequest
1 голос
/ 30 мая 2010

У меня есть два разных QuerySets, которые оба возвращают список пользователей (с разными полями). Как я могу отобразить их обоих в одной таблице HTML? Будет некоторое совпадение между тем, какие пользователи возвращаются, и для отсутствующих данных я просто хочу заполнить их нулями (что я, вероятно, могу сделать в шаблоне с фильтром default).

Если это помогает, запросы выглядят так:

new_users = User.objects.filter(date_joined__gt=sd, date_joined__lte=ed)
new_referrals = User.objects.filter(referrals__user__in=new_users).annotate(referral_count=Count('referrals')).select_related('profile')

accepted_bids = Bid.objects.filter(created__gt=sd, created__lte=ed, status='acc')
completed_shipments = Shipment.objects.filter(bids__in=accepted_bids)
vehicles_shipped = User.objects.filter(referrals__user__shipments__in=completed_shipments).annotate(vehicles_shipped=Count('referrals__user__shipments__items')).select_related('profile')

Мне нужно объединить new_referrals и vehicles_shipped, чтобы я мог перебрать его в своем шаблоне (объединенный с чем-то вроде user.id) или что-то в этом роде ... может быть, я могу каким-то образом использовать itertools в Python


Вот сгенерированный SQL для запроса vehicles_shipped:

SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined", COUNT("shipments_vehicleitem"."id") AS "vehicles_shipped", T7."id", T7."user_id", T7."company_name", T7."phone", T7."address_id", T7."referred_by_id", T7."user_type_id", T7."object_id", T7."credits" FROM "auth_user" LEFT OUTER JOIN "users_profile" ON  ("auth_user"."id" = "users_profile"."referred_by_id") LEFT OUTER JOIN "auth_user" T3 ON ("users_profile"."user_id" = T3."id") LEFT OUTER JOIN "shipments_shipment" ON (T3."id" = "shipments_shipment"."user_id") INNER JOIN "shipments_bid" ON ("shipments_shipment"."id" = "shipments_bid"."shipment_id") LEFT OUTER JOIN "shipments_vehicleitem" ON ("shipments_shipment"."id" = "shipments_vehicleitem"."shipment_id") LEFT OUTER JOIN  "users_profile" T7 ON ("auth_user"."id" = T7."user_id") WHERE ("shipments_bid"."created" <= E'2010-05-27 18:22:41.954766' AND "shipments_bid"."status" = E'acc' AND "shipments_bid"."created" > E'0001-01-01 00:00:00' ) GROUP  BY "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined", T7."id", T7."user_id", T7."company_name", T7."phone", T7."address_id", T7."referred_by_id", T7."user_type_id", T7."object_id", T7."credits"

Ответы [ 5 ]

1 голос
/ 09 июля 2011

Итак, этот вопрос уже устарел, но кажется, что вы могли бы просто сделать следующее:

new_users_by_id = dict([(u.id, u) for u in new_users])
vehicles_shipped_by_id = dict([(v.id, v) for v in vehicles_shipped])
mapped_users = {}
for id in keys(new_users_by_id):
    mapped_users[id] = dict(new_users_by_id[id].__dict__.items() + vehicles_shipped_by_id[id].__dict__.items())

Тогда mapped_users объединит пользователей.

Это просто отображает оба списка по их идентификаторам, а затем объединяет их вместе, как объяснено в этом SO-решении для объединения диктов .

1 голос
/ 31 мая 2010

В какой-то момент наборы результатов двух запросов необходимо перебрать и создать User объекты. Вы можете добавить это к шаблону или сделать это в виде, создавая set из User объектов (для устранения дубликатов). Затем либо передайте набор в шаблон, либо превратите его в список и сначала отсортируйте его.

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

1 голос
/ 31 мая 2010

Для большинства приложений вам не нужно ничего, кроме стандартных комбинаций django queryset. Это объединяет первичный ключ.

combined = new_referrals | vehicles_shipped

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

btw: & может использоваться для пересечения.

0 голосов
/ 31 мая 2010

Может это поможет вам? Объединяет два набора запросов и позволяет рассматривать их как один.

В качестве альтернативы, ударить их обоих с помощью list () в представлении: total_users = list (new_referrals) + list (Vehicles_shipped)

0 голосов
/ 31 мая 2010

Вы можете использовать JOIN

http://dev.mysql.com/doc/refman/5.1/en/join.html

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