2009-10-27 3 views
0

У меня есть запрос, который получает меня 32 аватар из моего аватара приложения:цепных запросы вместе в Django

newUserAv = Avatar.objects.filter(valid=True)[:32] 

Я хотел бы совместить это с запросом, чтобы Джанго модели Идент.польза, так что я могу получить последние последние 32 человека, у которых есть аватары, отсортированы по дате присоединения.

Каков наилучший способ связать эти два вместе?

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

image = models.ImageField(upload_to="avatars/%Y/%b/%d", storage=storage) 
user = models.ForeignKey(User) 
date = models.DateTimeField(auto_now_add=True) 
valid = models.BooleanField() 

Обратите внимание, что поле даты, дата аватара обновляется, поэтому не подходит для моего purporse

+0

Какая модель аватара связана с моделью пользователя? –

+0

Это пользовательская модель в качестве первичного ключа (извините, если мой синтаксис неверен, я изучаю здесь) –

+0

Можете ли вы обновить свое оригинальное сообщение с помощью кода модели 'Avatar'? – thornomad

ответ

2

Либо вы помещаете поле в свой собственный класс пользователя (возможно, вам придется подклассировать пользователя или составить django.contrib.auth.models.User), что указывает на то, что у пользователя есть аватар. Чем вы можете легко сделать свой запрос.

Или что-то вроде этого:

from django.utils.itercompat import groupby 
avatars = Avatar.objects.select_related("user").filter(valid=True).order_by("-user__date_joined")[:32] 
grouped_users = groupby(avatars, lambda x: x.user) 
user_list = [] 
for user, avatar_list in grouped_users: 
    user.avatar = list(avatar_list)[0] 
    user_list.append(user) 
# user_list is now what you asked for in the first_place: 
# a list of users with their avatars 

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

Объяснение фрагмента кода: Искатели из 32 последних пользователей, присоединившихся к пользователю, запрашиваются вместе с соответствующим пользователем, поэтому нет необходимости в запросе базы данных для любого из них в предстоящем коде. Список аватаров затем группируется с пользователем в качестве ключа. list получает все элементы из генератора avatar_list и первого элемента (должен быть только один) назначается user.avatar

Обратите внимание, что это не нужно, вы всегда можете сделать что-то вроде:

for avatar in avatars: 
    user = avatar.user 

Но возможно, более естественно получить доступ к аватарам пользователем .avatar.

+0

Stefanw - это выглядит очень хорошо. Я собираюсь попробовать, есть ли шанс добавить комментарии к вашему коду, чтобы я мог лучше понять, что он делает? –

+0

Это работает отлично (просто протестировано), но я бы хотел лучше понять код –

+0

Я добавил немного объяснений. – stefanw

0

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

Однако, если у вас есть чужой ключ от одной модели к другой, то добавление select_related() в ваш запрос будет извлекать связанные объекты в память в одном запросе БД, чтобы вы могли получить к ним доступ, не возвращаясь к БД ,

+0

Hi Gabriel, Я не уверен, что полностью понял, так как, например, я бы запросил у моей модели пользователя (я бы запросил всех пользователей/как если бы я ограничил ее до последних 32, у кого-то может не быть объекта аватара) а затем передать его - выполнение запроса для всех пользователей по дате присоединения датируется немного неэффективным? –

Смежные вопросы