显示Django DetailView旁边的对象列表

时间:2014-10-26 07:38:26

标签: python django django-class-based-views

我有一个非常简单的DetailView(CBV),它显示有关事件的详细信息。在这个DetailView中,我还展示了一个侧边栏“小工具”,其中列出了已经接近截止日期的5个事件。通过查询Event模型,在我的 models.py 中定义了在“DetailView”中显示此“ListView”的逻辑。

某事告诉我,这不是正确的事情。它目前正在工作......但是我(通过阅读文档后)感觉这种东西应该转移到视图而不是模型。

有没有办法“优化”当前的逻辑?

在我的 views.py

class SingleEventView(DetailView):
    model = Event
    template_name = 'single-event.html'

single-event.html 模板中,我通过在 models.py 中定义以下内容来显示最近的5个即将发生的事件的列表:

from django.db import models
from datetime import date

class Event(models.Model):
    # Model stuff

    class Meta:
        ordering = ['event_date']

    def approaching(self):
        today = date.today()
        approaching_event = Event.objects.exclude(event_date__lt=today)[:5]
        return approaching_event

这允许我在我的模板中执行以下操作:

<dl>
    {% for approaching in event.approaching %}
        <dt>{{ approaching.deadline|date:"F j" }}:</dt>
        <dd>{{ approaching.title }}</dd>
    {% endfor %}
</dl>

这个approaching方法应该是静态的吗?它应该是一个功能吗?它似乎......错了。想法?

1 个答案:

答案 0 :(得分:4)

如果此方法在模型实例的所有使用中都有正确的用例,那么您在模型中需要此功能的唯一原因。

也就是说,你不是在这里写仅用于视图

在这个特定示例中 - 您的方法存在于模型中,因为您实际上是使用模型实例作为在视图中调用此方法的方法。

想想另一种方式,如果你没有使用基于类的视图,你还会把这个方法放在模型中吗?

那么,现在的问题是在使用基于类的视图时如何将自定义对象发送到上下文中?

在所有基于类的视图(继承自ContentMixin)中,您可以覆盖get_context_data method以在上下文中返回自定义对象:

import datetime

from yourapp.models import Event

class SingleEventView(DetailView):
    model = Event
    template_name = 'single-event.html'

    def get_context_data(self, *args, **kwargs):
       # Get the existing context dictionary, then add
       # your custom object to it before returning it
       ctx = super(SingleEventView, self).get_context_data(*args, **kwargs)
       ctx['approaching'] = Event.objects.exclude(event_date__lt=datetime.date.today())[:5]
       return ctx

当然现在在你的模板中:

<dl>
    {% for approaching in approaching %}
        <dt>{{ approaching.deadline|date:"F j" }}:</dt>
        <dd>{{ approaching.title }}</dd>
    {% endfor %}
</dl>

如果您打算在不同的视图中使用它,最好创建一个custom context processor,以便无论这些对象如何被调用,您的所有视图都可以使用此对象。

import datetime

from yourapp.models import Event

def upcoming_events(request):
    now = datetime.date.today()
    return {'approaching': Event.objects.exclude(event_date__lt=now)[:5]}

将其保存在模块中,并将该模块路径添加到TEMPLATE_CONTEXT_PROCESSORS setting,保留默认值。

现在你不必担心&#34;手动&#34;发送对象列表,它将在从RequestContext继承的所有视图中可用(因此所有基于类的视图和使用render shortcut的任何视图)。