【问题标题】:Avoid duplication in Django for loop with a many to many relationship避免在具有多对多关系的 Django for 循环中重复
【发布时间】:2022-08-03 17:47:28
【问题描述】:

我的目标是列出创建的每个笔记的 tag_titles。

我遇到了问题,因为 tag_title 和 note 是通过多对多关系链接的。

我通常会这样做是:

{% for note_tag in note_tags %}
    {% if note_tag.note == note %}
        {{note_tag.tag_title}}
    {% endif %}
{% endfor %}

但是,因为 tag_title 和 NoteModel 是多对多的关系,所以 note_tag.note 给出 notes.NoteModel.None

我的模型.py如下面所述:


class NoteModel(models.Model):
    note = models.CharField(
        max_length = 5000,
    )

    note_title = models.CharField(
        max_length = 500,
        blank = False,
        null = True,
    )
    
    project = models.ForeignKey(
        IndividualProject,
        on_delete=models.CASCADE,
        related_name = \"note_projects\",
        blank = False,
        null = True,
    )

    tag = models.ManyToManyField(
        \'NoteTagModel\',
        related_name=\"tags\",
        blank= False,
        through = \"TaggedModel\"
    )

    def __str__(self):
        return f\"{self.note_title}\"

class NoteTagModel(models.Model):
    note = models.ManyToManyField(
        \'NoteModel\',
        related_name=\"tag_notes\",
        blank= False,
        through = \"TaggedModel\"
    )

    tag_title = models.CharField(
        max_length = 200,
        default = \"General\",
    )

    def __str__(self):
        return f\"{self.tag_title}\"

class TaggedModel(models.Model):
    note = models.ForeignKey(NoteModel, on_delete = models.CASCADE)
    tag = models.ForeignKey(NoteTagModel, on_delete = models.CASCADE)

    def __str__(self):
        return f\"{self.note} | {self.tag}\"

class TagCommentaryModel(models.Model):
    tag_title = models.ForeignKey(
        NoteTagModel,
        on_delete=models.CASCADE,
        related_name=\"tag\",
        blank = False,
        null = True,
    )

    tag_commentary = models.CharField(
        max_length = 5000
    )

    def __str__(self):
        return f\"Tag: {self.tag_title} | Tag Commentary: {self.tag_commentary}\"

我的上下文视图.py如下:



    context = {
        \'note_form\' : note_form,
        \'notes\' : NoteModel.objects.filter(project = obj),
        \'notes_tag\' : NoteTagModel.objects.all(),
        \'commentary\' : TagCommentaryModel.objects.all(),
        \'projects\' : IndividualProject.objects.all(),
        \'specific_project\' :  IndividualProject.objects.get(id=id),
        \'obj\' : IndividualProject.objects.get(id=id),
        \'tagged\' : TaggedModel.objects.all(),
        
    }


    return render(request, \"notes/specific-note.html\", context)

我的 django 模板如下:

<div class = note_overview_container>
    {% for note in notes %} 
        <div class = individual_note_container> 
                <div class = note_title>
                {{ note.note_title }}
                </div>
                {% for note_tag in notes_tag %}
                    <div class = tag_title>
                    {{ note_tag.tag_title }}
                    </div>
                <ul class = tag_commentary>
                {% for commentary in commentary %}
                        {% if note_tag == commentary.tag_title %}
                            {% if note == commentary.note %}
                            <li>{{ commentary.tag_commentary }}</li>
                            {% endif %}
                        {% endif %}
                {% endfor %}
                </ul>
                {% endfor %}
        </div>
    {% endfor %}    
</div>

    标签: python django django-models django-views django-templates


    【解决方案1】:

    在我看来,你可以大大简化你的模型。您从 NoteModel 中的标签指向 NoteTagModel,反之亦然,我认为不需要。 TaggedModel 也似乎是多余的。至少如果没有像您那样链接它的特定理由。

    class NoteModel(models.Model):
        note = models.CharField(max_length = 5000)
        note_title = models.CharField(max_length=500, blank=False, null=True)
        project = models.ForeignKey(IndividualProject, on_delete=models.CASCADE, related_name="note_projects", blank=False, null=True)
        # plural
        tags = models.ManyToManyField(NoteTagModel, related_name="tags", blank=False)
        
        def __str__(self):
            return self.note_title
        
    class NoteTagModel(models.Model):
        # usually there is no need to point here again to the same model thats already pointing to this one
        tag_title = models.CharField(max_length=200, default="General")
        
        def __str__(self):
            return self.tag_title
    

    如果您想从 NoteTagModel 访问反向到 NoteModel,您可以执行以下操作,例如:

    for tag in NoteTagModel.objects.all():
        for note in tag.nodemodel_set.all():
            print(note.note_title)
            …
    

    (我把 html 类放在双引号中)

    <div class="note_overview_container">
        {% for note in notes %}
            <div class="individual_note_container"> 
                <div class="note_title">
                    {{ note.note_title }}
                </div>
    
                <!-- loop over all the tags related to the note -->
                {% for tag in note.tags.all %}
                    <div class=”tag_title”>
                        {{ tag.tag_title }}
                    </div>
    
                    <ul class="tag_commentary">
                        <!-- commentary in commentary shouldnt be named the same -->
                        {% for comment in commentary %}
                            {% if note_tag == comment.tag_title %}
                                {% if note == comment.note %}
                                    <li>{{ comment.tag_commentary }}</li>
                                {% endif %}
                            {% endif %}
                        {% endfor %}
                    </ul>
                {% endfor %}
            </div>
        {% endfor %}    
    </div>
    

    【讨论】:

      猜你喜欢
      • 2019-12-26
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多