检查对象是否在相关对象的QuerySet中

时间:2010-08-19 07:33:47

标签: django django-templates

我正在构建一个与游戏成就有关的应用程序,我想为每个游戏显示一个列出相关成就的页面。这样就完成了。

但是,我还希望每个用户都能够在该列表中看到他们已完成哪些成就。

我的模型是这样的:

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()

在游戏模板页面中,我通过与成就模型的关系(即achievements = game.achievement_set.all)获得当前游戏的所有成就。然后我对它们进行{% for ach in achievements %}并为每个输出<li>。 如果用户已登录,我还想显示与成就相关联的curr_count。因此,我需要特定GameProfile的Achieved对象列表(将其视为当前用户)。

问题是我无法做{% if ach in achieved %}(其中ach是一个Achievement实例并且实现了一个Achieved QuerySet)。

我还以为我可以使用用户已经实现的成就获得QuerySet,但是缺少我要显示的curr_count

我认为我想要的是某种带有用户成就的列表或字典,如果特定的成就是成员,我可以测试它,但是它也会带有curr_count变量。另一个解决方案可能是以某种方式将curr_count作为字段添加到Achievement对象的QuerySet(这将是用户已实现的对象)。

你能建议如何在django中完成这个任务吗?

1 个答案:

答案 0 :(得分: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>)

<强>更新

显然我误解了这个问题。这是另一个刺痛。

@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 %}