在Django模板中如何判断request.user是否在与用户相关的对象列表中?

0 投票
1 回答
591 浏览
提问于 2025-04-18 01:34

我有一个Django模型,长得像这样:

from django.contrib.auth.models import User
class Cohort(models.Model) :
    cohort_name = models.CharField(max_length=64, primary_key=True)
    cohort_description = models.TextField(null=False)
    creation_date = models.DateTimeField(default=now)

class CohortMembers(models.Model) :
    cohort = models.ForeignKey(Cohort)
    member = models.ForeignKey(User)
    creation_date = models.DateTimeField(default=now)

你可以看到,Cohorts(小组)和Users(用户)之间是多对多的关系。

在一个模板中,我列出了小组,像这样(简化一下让你明白):

{% for cohort in object_list %}
  <a href="./{{ cohort.cohort_name }}/">{{ cohort.cohort_name }}</a>
  <!-- list all members of the cohort -->
  {% for cohortmember in cohort.cohortmembers_set.all %}
    {% if request.user.username == cohortmember.member.username %}
      <!-- the user is a member of the cohort, provide a delete button -->
      <button>Leave cohort</button>
    {% else %}
      Some other user called {{ cohortmember.member.username }} is a member.
    {% endif %}
  {% endfor %}
{% endfor %}

我需要做的是,给用户提供一个按钮,让他们可以在还不是小组成员的情况下加入这个小组。在最简单的Python代码中,你可能会这样做:

# clearly some better python would be to use a django model query, rather
# than iterate over the members, but this encapsulates the basic logic
is_member = False
for cohortmember in cohort.cohortmembers_set.all:
     if request.user == cohortmember.member:
        is_member = True
if is_member :
     # a leave button
else:
     # a join button

我能在Django的模板语言中做到这些吗?还是说我必须把这样的代码放到View类里面去?

1 个回答

0

我找到的唯一真正有效的方法是结合操作CohortView和一些简单的模板编程。

我把问题换了个角度:不是问“这个用户是不是那个组的成员?”而是问“这个组在用户的会员列表里吗?”这样简单明了。

在CohortListView的get_context_data中如下:

def get_context_data(self, **kwargs) :
    context = super(CohortListView, self).get_context_data(**kwargs)
    memberships = CohortMembers.objects.filter(member=self.request.user)
    cohorts = []
    for membership in memberships:
        cohorts.append(membership.cohort)
    context['memberships'] = cohorts
    return context

注意,我放弃了多对多的对象,而是直接在上下文中存储用户所加入的组的列表。

然后,在模板中:

{% for cohort in object_list %}
  {% if cohort in memberships %}
    <!-- leave button -->
  {% else %}
    <!-- join button -->
  {% endif %}
{% endfor %}

撰写回答