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