我有两个模型-Note和Pinboard-在Django应用中具有多对多关系。这两个模型通过另一个模型-Pin进行了关联,因此我可以存储有关该关系的其他信息。

我想在DetailView的Pinboard中显示相关的Note实例。那不是问题。但是我想预取注释,并在position表的through字段上对它们进行排序。

关于如何存档的任何提示(在第三张桌子上预取+排序)?



到目前为止,这就是我所需要的……从某种意义上说,它是有效的,我不必查询每个条目,但是我发现没有办法通过它们的position来对Note实例进行排序,而无需为每个实例进行更多查询。

楷模

from django.db import models


class Note(models.Model):

    title = models.CharField(max_lenght=200)

    content = models.TextField()


class Pinboard(models.Model):

    title = models.CharField(max_lenght=200)

    notes = models.ManyToManyField(
        Note, blank=True, related_name='pinboards', through='Pin'
    )


class Pin(models.Model):

    class Meta:
        ordering = ['position', ]
        get_latest_by = 'position'

    pinboard = models.ForeignKey(Pinboard, related_name='note_pins')

    note = models.ForeignKey(Note, related_name='pinboard_pins')

    position = models.PositiveSmallIntegerField(default=0)


视图

from django.views.generic import DetailView


class PinboardDetailView(DetailView):

  model = Pinboard

  queryset = Pinboard.objects.prefetch_related('notes')


模板

{% extends 'base.html' %}
{% block content %}
<h1>{{ pinboard.title }}</h1>
{% if pinboard.notes.all.exists %}
    <ol>
    {% for note in pinboard.notes %}
        <li>{{ note.title }}</li>
    {% endfor %}
    </ol>
{% else %}
    <p>Nothing here yet…</p>
{% endif %}
{% endblock content %}

最佳答案

我建议您使用Prefetch object

class PinboardDetailView(DetailView):
    model = Pinboard
    queryset = Pinboard.objects.prefetch_related(
        Prefetch(
            'notes',
            Note.objects.order_by('pinboard_pins__position'),
        )
    )


顺便说一句,您完全不需要在prefetch_related上使用DetailView,因为它将导致相同数量的查询。

另外,since you're already fetching the pinboard.notes我建议您使用{% if pinboard.notes.all %}而不是{% if pinboard.notes.all.exists %}

09-20 04:04