列表视图中的Django CBV排序不起作用

时间:2014-04-27 20:14:45

标签: django django-views

我不确定出了什么问题,但我无法订购CBV中生成的列表。我按照django文档https://docs.djangoproject.com/en/1.6/topics/class-based-views/mixins/#using-singleobjectmixin-with-listview中的说明进行操作。该模型如下:

class Event(models.Model):
...
    venue = models.ForeignKey(
        'app_place.PointOfInterest',
        related_name='events',
        verbose_name=_('Event Place'),
    )
    start = models.DateTimeField(
        default=timezone.now(),
        verbose_name=_('Start date'),
    )

    def sorted_events_set(self):
        return self.event_set.order_by('start')

views.py包含:

class PoiDetail(SingleObjectMixin, ListView):
...
    def get_queryset(self):
        return self.object.events.all()

一切都很好,但html页面中的列表按ID排序(顺便说一下)。所以我添加了order_by:

return self.object.events.all().order_by('start')

但它不起作用(顺序保持不变)。到底是怎么回事?这不是正确的方法吗?我还尝试在其他问题中建议在模型中添加特定排序,但后来我遇到了不同的错误,我不知道如何用sorted_events_set方法编写return语句。 谢谢你的帮助!

修改

这是完整的views.py

class PoiDetail(SingleObjectMixin, ListView):
    template_name = 'app_place/poi.html'

    def get(self, request, *args, **kwargs):
        self.object = self.get_object(queryset=PointOfInterest.objects.all())
        return super(PoiDetail, self).get(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(PoiDetail, self).get_context_data(**kwargs)
        context['poi'] = self.object
        return context

    def get_queryset(self):
        return self.object.events.all().order_by('start')

这是模板:

{% for event in poi.events.all %}
    <a href="/e20/event/{{event.id}}" class="list-group-item">
    <h4 class="list-group-item-heading">{{ event.title }}</h4>
    <p class="list-group-item-text">{{event.description}}</p>
    </a>
{% endfor %}

1 个答案:

答案 0 :(得分:1)

首先,我建议不要混用SingleObjectMixinListView。它们是针对两个不同的目标而编写的,并且与它们实现这些目标的方式不相容。你可以像你一样修补它,但是如果你不是很小心,你仍然会遇到很多意想不到的行为,特别是在依赖对super的调用时。您实际上只是尝试创建详细信息视图,因此您应该将DetailView作为模型进行子类化PointOfInterest

现在您的排序问题:您无法将参数传递给模板中的函数,因此您必须在视图中对上下文中的查询集进行排序,或者创建一个没有任何(必需)的函数参数。我将使用第一种方法,在视图代码中保留视图的逻辑,并防止使用辅助方法使模型混乱。无论哪种方式,您都必须跟踪您正在使用的查询集,因为排序一个查询集不会影响另一个查询集。

所以要使用上下文方法:

class POIDetail(DetailView):
    model = PointOfInterest

    def get_context_data(self, **kwargs):
        context = super(POIDetail, self).get_context_data(**kwargs)
        context['sorted_event_list'] = self.object.events.order_by('start')
        return context

在您的模板中,使用{% for event in sorted_event_list %}进行迭代。