如何在Django中显示多对多关系的元素?

时间:2013-09-26 19:02:26

标签: python django django-models

我有以下模特:

class Topic(models.Model):
    title = models.CharField(max_length=140)

    def __unicode__(self):
        return self.title
    class Meta:
        verbose_name = _('topic')
        verbose_name_plural = _('topics')

class TopicLabel(models.Model):
    name = models.CharField(max_length=256)
    order = models.IntegerField(null=True, blank=True)

    def getTopics():
        return TopicLabelConnection.objects.filter(labelId=self.id).orderby('order')

    def __unicode__(self):
        return self.name


class TopicLabelConnection(models.Model):
    topicId = models.ForeignKey(Topic, related_name='connection_topic')
    labelId = models.ForeignKey(TopicLabel, related_name='connection_label')

    def __unicode__(self):
        return self.labelId.name + ' / ' + self.topicId.title

  • 主题
  • TopicLabels
  • 他们之间的联系( TopicLabelConnection )。

可以为多个主题分配一个标签。

我想显示一个具有以下结构的有序列表:

  1. 标签1
    1. 主题1
    2. 主题2
    3. 主题3
  2. 标签2
    1. 主题4
    2. 主题5
    3. 主题6
  3. 其中主题1,2和分配给标签1和主题4,5和6 - 标记为2.

    为此,我创建了如下所示的视图功能和HTML模板片段。

    查看功能

    def home(request):      
        labels = TopicLabel.objects.filter(connection_label__isnull=False).distinct().order_by('order')
    
        return TemplateResponse(request, 'home.tpl.html', locals())
    

    模板片段

    <ol>
        {% for cur_label in labels %}
            <li>{{ cur_label.name }}</li>
            <ol>
            {% for cur_topic_label_connection in cur_label.getTopics %}
                <li>{{ cur_topic_label_connection.topicId.title }}</li>
            {% endfor %}
            </ol>
        {% endfor %}    
    </ol>
    

    结果:仅显示标签,但不显示主题。

    我应该如何更改代码,以便标签和主题都显示在层次结构列表中?

2 个答案:

答案 0 :(得分:1)

您没有正确过滤。

问题在于getTopics方法

请改为尝试:

return TopicLabelConnection.objects.filter(labelId__id=self.id).order_by('order')

注意labelId是一个TopicLabel,而不是它的id

答案 1 :(得分:1)

您应该使用正确的ManyToMany字段:

class TopicLabel(models.Model):
    ...
    topics = models.ManyToManyField(Topic, through=TopicLabelConnection)

现在可以移除getTopics方法,您可以在模板中执行此操作:

{% for topic in cur_label.topics.all %}
    <li>{{ topic.title }}</li>
{% endfor %}

请注意,order_by中的getTopics电话无意义,因为唯一具有order字段的模型是TopicLabel,但您正在尝试获取无主题的主题订单领域。