我有大概这样的模型:
class Person(models.Model):
...
name = models.CharField(max_length=40)
eyes = models.CharField(max_length=12)
...
relationships = models.ManyToManyField('self', through='Relationship',
symmetrical=False, related_name='related_to')
class Relationship(models.Model):
from_person = models.ForeignKey(Person, related_name='from_people', ...)
to_person = models.ForeignKey(Person, related_name='to_people', ...)
status = models.CharField(max_length=20)
我有合理的数据库条目,可以在Python shell中看到它们:
>>> p1 = Person.objects.get(...)
>>> r = Relationship.objects.filter(from_person=p1)
<QuerySet [<Relationship: p1 p2 status>], [<Relationship: p1 p99 status>]>
>>> r[0].status
Friend
>>> r[0].from_person.name
p1
>>> r[0].from_person.eyes
Brown # p1's eye color
>>> r[0].to_person.name
p2
>>> r[0].to_person.eyes
Blue # p2's eye color !!!
现在我想从我的模板中访问相同的信息,但我看不到我的期望:
<p>name={{ person.name }} ({{ person.eyes }})</p>
<p>len={{ person.relationships.all|length }}</p>
{% for rel in person.relationships.all %}
<p> rel[{{ forloop.counter }}]={{ rel.status }}
{{ rel.from_person.name }} ({{ rel.from_person.eyes }})
{{ rel.to_person.name }} ({{ rel.to_person.eyes }})</p>
{% endfor %}
显示:
name=p1 (Brown)
len=2
rel[0]=
rel[1]=
我期待:
name=p1 (Brown)
len=2
rel[0]=Friend p1 (Brown) p2 (Blue)
rel[1]=Enemy p1 (Brown) p99 (Red!)
我在“关系”模型中添加了访问器方法,但它没有什么区别。 我使用模板“切片”过滤器搞砸了。 我错过了一些基本的东西......
感谢您的帮助!
编辑:此模板代码执行上述示例所需的操作。感谢以下两位评论者:
{% for rel in person.from_people.all %}
<p> rel[{{ forloop.counter }}]={{ rel.status }}
{{ rel.from_person.name }} ({{ rel.from_person.eyes }})
{{ rel.to_person.name }} ({{ rel.to_person.eyes }})</p>
{% endfor %}
答案 0 :(得分:0)
查看Person
模型中的这行代码:
relationships = models.ManyToManyField('self', through='Relationship', ...)
如果您处理relationships
实例的属性Person
,则会返回目标模型的管理器(也是Person
)。
因此p1.relationships.all()
会返回与p1
相关的所有人,而非关系实例。
如果您想访问through
模型的中间数据,则必须直接查询:
Relationship.objects.filter(from_person=p1)
另请参阅Docs (Django 2.0): Extra fields on many-to-many relationships
中的示例编辑:Dan的评论可能会显示从模板中给定Person的访问关系数据的正确方法。我认为模板语言应该能够处理后向关系。你可以尝试一下,告诉它是否有效吗?
<p>name={{ person.name }} ({{ person.eyes }})</p>
<p>len={{ person.relationships.all|length }}</p>
{% for rel in person.from_people.all %}
{# rel is now a Relationship where 'from_person' is 'person' #}
<p> rel[{{ forloop.counter }}]={{ rel.status }}
{{ rel.from_person.name }} ({{ rel.from_person.eyes }})
{{ rel.to_person.name }} ({{ rel.to_person.eyes }})</p>
{% endfor %}
答案 1 :(得分:0)
此模板代码执行上述示例所需的操作。感谢两位评论者:
{% for rel in person.from_people.all %}
<p> rel[{{ forloop.counter }}]={{ rel.status }}
{{ rel.from_person.name }} ({{ rel.from_person.eyes }})
{{ rel.to_person.name }} ({{ rel.to_person.eyes }})</p>
{% endfor %}