Django 模板 - 显示多对多关系

Django Template - show many-to-many relationship

在 Flask 中构建了一些基本应用程序后,我正在学习 Django。我想做的一件事是向用户显示所有 post 的列表,以及他们是否遵循给定的 post。但是,Jinja 或 Django 抛出了一些我不太清楚如何调试的错误。

Models.py

class User(models.Model):
    id = models.AutoField(primary_key=True)
    username = models.CharField(unique=True, max_length=120,blank=False)
    password = models.CharField(max_length=120, blank=True, null=False)

class Record(models.Model):

    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=120, unique=True, blank=True)
    followers = models.ManyToManyField(User, through='Follow')

class Follow(models.Model):

    id = models.AutoField(primary_key=True)
    record = models.ForeignKey(Record)
    user = models.ForeignKey(User)
    date_followed = models.DateField(null=True, blank=True)

records.html

{% for i in records %}

  {% if i.follow.filter(id='1').first() %}
    DO SOMETHING
  {% endif %}     

{% endfor %}

错误

TemplateSyntaxError at /records/
Could not parse the remainder: '(id='1').first()' from 'i.follow.filter(id='1').first()'

为了在我 运行 python manage.py shell 并执行以下命令时进行测试,我没有遇到任何问题:

>>> x = Record.objects.first()
>>> x.followers.filter(id='1').first()
  <User: User object>

我最初使用 Flask 制作了这个应用程序的原型,并使用了以下 jinja 模板并且从未遇到过问题:

{% for i in accounts %}

  {% if i.follow.filter_by(user_id='1').first() %}
    DO SOMETHING
  {% endif %}

{% endfor %}

您不能在模板中执行该逻辑。您可以在 Record 模型中创建一个为您完成的方法,您可以在模板

中调用它
class Record(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=120, unique=True, blank=True)
    followers = models.ManyToManyField(User, through='Follow')

    def first_follower(self):
        if self.follow_set.filter(user_id=1).exists():
            return True
        return False

并在模板中:

{% for i in records %}
    {% if i.first_follower %}
         DO SOMETHING
    {% endif %}     
{% endfor %}

这是设计使然 https://code.djangoproject.com/ticket/1199

想法是,django 模板应该专注于设计,对于设计师来说,让更复杂的代码 运行 在 Python 中,而不是在模板呈现时。

因此,如果您使用此检查时这是单个实例,请将其添加到视图中:

def get_context_data(self,*arg,**kwargs):

  context = super(MyRecordView,self).get_context_data(*args,**kwargs)
  context[has_follow] = self.object.follow.filter_by(user_id='1').exists()
  return context

在模板中:

{% if has_follow %}
...
{% endif %}

但是,如果您经常使用此检查,则可以将其添加到您的模型中:

def has_follow(self):
   return self.follow.filter_by(user_id='1').exists()

然后您可以在模板中访问它,w/o 对视图上下文的任何更改,因为它是模型属性:

{% if i.has_follow %}
...
{% endif %}