【问题标题】:Check whether object is in QuerySet of related objects检查对象是否在相关对象的QuerySet中
【发布时间】:2010-08-19 07:33:47
【问题描述】:

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

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

我的模型是这样的:

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。因此,我需要特定 GameProfile 的已实现对象列表(将其视为当前用户)。

问题是我不能做{% if ach in achieved %}(其中ach 是一个Achievement 实例并实现了一个Achieved QuerySet),显然。

我还认为我可以获得一个包含用户已取得成就的 QuerySet,但它缺少我想要显示的 curr_count

我想我想要的是某种包含用户成就的列表或字典,我可以根据这些列表或字典来测试特定成就是否是成员,但它也会携带 curr_count 变量。另一种解决方案可能是以某种方式将curr_count 作为字段添加到成就对象的查询集(这将是用户已经实现的对象)。

您能建议如何在 django 中完成此操作吗?

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    如果您的 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 %}
    

    【讨论】:

    • 感谢您的回答,但我认为这无关紧要。我知道如何生成仅包含当前用户成就的查询集。我的问题是,如果我有那个查询集,并且我正在循环一个成就查询集,我如何测试成就实例是否包含在成就查询集中,这是一个不同的模型(因此,{% if ... in %} 测试不起作用),然后从查询集的特定已实现条目中检索字段的值。
    • 三分。 (1) 显然我没有正确理解你的问题。对不起(2)我不知道使用Django的内置过滤器检查Achievement的实例是否在Achieved查询集中的比较(3)恕我直言,您最好在视图中进行此过滤而不是在模板中。也就是说,您可以编写一个自定义过滤器函数来测试Achievement 是否存在于Achieved 查询集中。在后台过滤器函数会执行一个过滤器查询到er,实现这个。
    • 已经用这种过滤器的粗略示例更新了我的答案。
    • 谢谢!这确实解决了问题。我也更愿意在视图而不是模板中执行此操作,但我不知道如何完成。我不知何故需要在成就列表上的循环的每次迭代中获取正确的成就对象,这是在模板上完成的。你能简要地勾勒一下我可以在视图中以什么方式做到这一点吗?
    猜你喜欢
    • 1970-01-01
    • 2016-01-15
    • 2018-02-23
    • 1970-01-01
    • 2013-09-26
    • 2020-07-09
    • 2015-01-19
    • 1970-01-01
    • 2018-09-10
    相关资源
    最近更新 更多