Django:为同一数据提供多个视图的最佳方式是什么,最好每种方式的呈现方式不同?

时间:2010-12-18 19:14:32

标签: django model-view-controller templates views django-templates

有可能吗?

我的问题是,我的主页上有几列,所有这些列都需要使用不同的过滤器和不同的模型来显示模型。我不想获取模型并在视图中对其进行过滤,然后将它们作为变量传递给包含所有“model1_filterAppliedA”,“model1_filterAppliedB”的主页。这似乎有点矫枉过正。我想要一个很好的方式来说“在此列中显示此模型的这个文件化查询集”“在另一列中使用此过滤器显示此其他查询集”。

在django中实现这一目标的最佳方法是什么?

由于

编辑:

经过一段时间的实验;

选项1:

我有一个看起来像这样的模板标签

@register.inclusion_tag('app/accordion_column.html', takes_context=True)
def accordion_by_filter(context, f):
    user = context['request'].user
    print "f: " + str(f)

    filetered_mobjects = Modell.objects \
                            .filter(creator=user.userprofile) \
                            .filter(state=f) \
                            .order_by('-created')[0:10]

    return {'mobjects': filetered_mobjects}

然后从我的模板中用

调用它
{% load mytags %}
{% accordion_by_filter 'A' %}

accordion_column.html扩展了我的其他模板,只是遍历了mobjects。 现在,当我需要在main_column中显示所有的mobject但用'B'过滤时我会做同样的事情,但用accordion_by_filter'B'调用它

因此对于索引视图,其中包含accordion_column(向左)main_column和right_sidebar。将对数据库进行三次单独的匹配,以便应用每个过滤器。这是我认为没问题,因为另一种选择是获取所有的mobject并过滤结果列表?

选项2;过滤器,加载任何模板的视图应该获取所有或某些模型,并将其沿变量铲到模板中,然后通过模板过滤器像普通列表一样进行过滤。所以这应该是一次数据库之旅,但结果会更重,并且它的过滤将在templatefilter中多次计算,而不是告诉数据库这样做。

过滤器:

@ register.filter def state(mobjects_list,arg):

filtered = []
for p in mobjects_list:
    if p.state == arg:
        filtered.append(p)

return filtered

在视图返回我可以做的mobjects的任何模板中

for p in mobjects|state:'A'
    ....

哪个选项更好,最快?

1 个答案:

答案 0 :(得分:0)

听起来上下文处理器就是你想要的。基本上,您可以编写一个上下文处理器,它将为每个RequestContext添加一些上下文。上下文处理器可能看起来像这样(我通常把它们放在一个文件project_directory / app_directory / context_processors.py中):

from project.app.models import Book

def number_of_books(request):
    return {'num_books': Book.objects.all().count()}

然后,在项目的settings.py中,将此文件添加到TEMPLATE_CONTEXT_PROCESSORS元组中:

TEMPLATE_CONTEXT_PROCESSORS = ('app.context_processors.number_of_books', 'other', 'stuff')

最后,您必须使所有视图函数都使用RequestContext而不是普通的旧Context。通用视图自动使用RequestContext。如果您正在使用render_to_response,则必须添加context_instance kwarg(此示例中的'name'只是已在本视图中作为上下文传递的局部变量):

from django.template import RequestContext

def my_view(request):
    # ... some code, including assigning the 'name' variable to something ...
    return render_to_response("app/template.html", {'name': name},
                       context_instance=RequestContext(request))

我最喜欢的确保使用RequestContext的方法是使用django-annoying(第三方方便的东西)中的render_to装饰器:https://bitbucket.org/offline/django-annoying/wiki/Home

现在,每次渲染模板时,它将拥有来自其自己的视图的所有常规上下文变量以及来自上下文处理器的上下文变量。在我的示例中,您的书店网站可能在每个页面的标题中都有一行,上面写着“现在提供3,141,592本书!”假设您有一个名为base.html的基本模板,所有其他模板都会扩展,您可以这样做:

<div id="header">
  <h1> Cool Online Bookstore </h1>
  <p> Now offering {{ num_books }} books! </p>
</div>