2010-08-19 4 views
2

Я создаю приложение, связанное с достижениями игры, и хочу отображать для каждой игры страницу, на которой перечислены соответствующие достижения. Это сделано.Проверьте, находится ли объект в QuerySet связанных объектов

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

Моя модель выглядит так:

class Achievement(models.Model): 
    game = models.ForeignKey(Game) 
    ... 

class Game(models.Model): 
    ... 

class GameProfile(models.Model): 
    achievements = models.ManyToManyField(Achievement, through='Achieved') 
    ... 

class Achieved(models.Model): 
    profile = models.ForeignKey(GameProfile) 
    achievement = models.ForeignKey(Achievement) 
    curr_count = models.PositiveSmallIntegerField() 

На странице шаблона игры, я получаю все достижения для текущей игры через отношения с моделью Achievement (т.е. achievements = game.achievement_set.all). Затем я делаю {% for ach in achievements %} на них и вывожу <li> для каждого. Если пользователь вошел в систему, я также хочу отобразить curr_count, связанный с достижением. Поэтому мне нужен список объектов Achieved для определенного GameProfile (подумайте об этом как о текущем пользователе).

Проблема заключается в том, что я не могу сделать {% if ach in achieved %} (где ach является экземпляром достижения и достиг Достигнутого QuerySet), очевидно.

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

Я думаю, что я хочу, это какой-то список или словарь с достижениями пользователя, против которых я могу проверить, является ли конкретный Достижение членом, но который также будет нести переменную curr_count. Другим решением может быть как-то добавить curr_count в качестве поля для объектов QuerySet of Achievement (которые будут достигнуты пользователем).

Можете ли вы предложить, как это сделать в джанго?

ответ

3

Если у вашей модели GameProfile есть ссылка на (auth.)User, тогда вы можете создать следующий запрос и отправить его в шаблон.

def achievements_by_user(request, *args, **kwargs): 
    user = request.user 
    queryset = Achieved.objects.filter(profile__user = user) 
    return render_to_response(...) 

Этот queryset будет фильтровать все строки из Achieved на основе текущего пользователя. Если вы также хотите отфильтровать на основе игры (т. Е. Вернуть все достижения для текущего зарегистрированного пользователя для конкретной игры), вы можете добавить другое условие фильтра.

queryset = Achieved.objects.filter(profile__user = user, 
      achievement__game = <a game>) 

Update

Видимо, я неправильно понял вопрос. Вот еще один удар.

@register.filter 
def achievement_in(achieved, achievement): 
    count = achieved.filter(achievement = achievement).count() 
    return count > 0 

# In template 
{% for ach in achievements %} 
    {% if achieved|achievement_in:ach %} 
     ... 
    {% else %} 
     ... 
    {% endif %} 
{% endfor %} 
+0

Спасибо за ваш ответ, однако я считаю, что это не имеет значения. Я знаю, как создать набор запросов только с достижениями текущего пользователя. Мой вопрос в том, что если у меня есть этот запрос, и я просматриваю набор запросов «Достижения», как я могу проверить, содержится ли экземпляр достижения в заданном наборе запросов, который является другой моделью (следовательно, {% if ... in %} не работает), а затем извлекает значение поля из этой конкретной полученной записи набора запросов. – FrontierPsycho

+0

Три точки. (1) По-видимому, я правильно не понял ваш вопрос. Извините (2) Я не знаю сравнения, которое проверит, если экземпляр «Достижения» в задаче «Достигнутый» с использованием встроенных фильтров Django (3) IMHO вам лучше сделать эту фильтрацию в представлении а не в шаблоне. Тем не менее, вы можете написать функцию пользовательского фильтра, которая проверяет, присутствует ли «Достижение» в задаче «Достигнутый».За кулисами функция фильтра выполнила бы запрос фильтра на er, чтобы добиться этого. –

+0

Обновили мой ответ с примерным примером такого фильтра. –

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