Django模板:在用对象填充页面时如何随机化顺序?

时间:2015-03-03 16:57:24

标签: python html django python-3.x django-template-filters

我有一个Survey和一个Choice模型,每个调查都有许多与之相关的选择。当我使用所有选项呈现实际的HTML调查页面时,我使用以下Django模板代码:

{% for choice in survey.choice_set.all %}
    <li class="ui-state-default" choice_id={{ choice.id }}>{{ choice.choice_text }}</li>
{% endfor %}

然而,我不是每次都以相同的顺序出现选择,而是希望他们以随机顺序填充以减少任何潜在的偏见效应(例如,有人可能更有可能投票选择首先出现的选项在名单上。)

如果有一种方法可以在模板本身内执行此操作,那就太棒了,但我似乎更有可能需要在views.py中的后端执行某些操作。我已经尝试过这个,没有效果:

class DetailView(generic.DetailView):
    model = Survey
    ...
    def get_context_data(self, **kwargs):
        context = super(DetailView, self).get_context_data(**kwargs)
        ...
        survey = get_object_or_404(Survey, survey_link__iexact=survey_link)
        ...
        if randomize_choice_order:
            survey.choice_set.order_by('?')
        ...
        return context

知道我怎么能做到这一点?也许我需要开发一个JS函数来在对象已经放置后随机化它们?

2 个答案:

答案 0 :(得分:6)

您可以创建自定义模板标记以随机播放结果。

# app/templatetags/shuffle.py
import random
from django import template
register = template.Library()

@register.filter
def shuffle(arg):
    aux = list(arg)[:]
    random.shuffle(aux)
    return aux

然后在你的模板中

{% load shuffle %}
{% for choice in survey.choice_set.all|shuffle %}

答案 1 :(得分:0)

使用Django 1.7+,您可以使用Prefetch对象:

survey = get_object_or_404(
    Survey.objects.prefetch_related(
        Prefetch('choice', queryset=Choice.objects.order_by('?'),
                 to_attr='random_choices')
    ),
    survey_link__iexact=survey_link
)

然后,您可以使用survey.random_choices访问随机集。 survey.choice_set.all()仍可使用原始选项集。