能否在Django的dictsort过滤器中使用模板变量?
Django模板中使用变量作为dictsort排序键的问题
我尝试通过下拉按钮的排序选项对博客标题列表进行排序,相关代码如下:
下拉菜单代码
... <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="{% url 'profile-sorted' passed_user.pk 'title' %}">alphabet</a> <a class="dropdown-item" href="{% url 'profile-sorted' passed_user.pk '-post_date' %}">post date</a> </div>
URL配置
urlpatterns = [ ... path('user/<int:pk>', views.profile, name='profile'), path('user/<int:pk>/sorted/<str:sorting>', views.profile, name='profile-sorted'), ]
视图函数
def profile(request, pk, sorting='title'): user = User.objects.get(pk=pk) context = {'passed_user': user, 'sorting': sorting} return render(request, 'feed/profile.html', context=context)
模板排序部分
{% for blog in passed_user.blog_set.all|dictsort:"{{ sorting }}" %} <div class="row"> <div class="col"> <h6 class="mb-0">{{ forloop.counter }}. <a href="{% url 'blog-detail' blog.pk %}">{{ blog }}</a> </h6> </div> </div> <hr> {% endfor %}
遇到的问题:使用dictsort:"{{ sorting }}"时列表变为空,但直接写dictsort:"title"时能正常按标题排序。已确认sorting变量能返回正确字符串,想知道能不能用变量作为dictsort的排序键?
解决方案
问题出在模板语法的使用上,dictsort过滤器接收的是变量名本身,不需要用双花括号包裹。你现在写的"{{ sorting }}"相当于把sorting变量的值转成了字符串字面量传递给过滤器,而不是传递变量本身。
方案1:修正模板中的dictsort用法
修改模板里的排序代码,去掉双花括号:
{% for blog in passed_user.blog_set.all|dictsort:sorting %} <div class="row"> <div class="col"> <h6 class="mb-0">{{ forloop.counter }}. <a href="{% url 'blog-detail' blog.pk %}">{{ blog }}</a> </h6> </div> </div> <hr> {% endfor %}
方案2:在视图层完成排序(更推荐)
如果你的排序字段需要支持负号前缀(比如-post_date实现倒序),dictsort本身不支持这种语法,因为它只能接收普通的字段名。这种情况下建议在视图层完成排序逻辑,性能也更优:
修改视图函数:
def profile(request, pk, sorting='title'): user = User.objects.get(pk=pk) # 根据sorting参数对博客进行数据库层面排序 blogs = user.blog_set.all().order_by(sorting) context = {'passed_user': user, 'sorting': sorting, 'blogs': blogs} return render(request, 'feed/profile.html', context=context)
模板里直接遍历排序后的blogs:
{% for blog in blogs %} <div class="row"> <div class="col"> <h6 class="mb-0">{{ forloop.counter }}. <a href="{% url 'blog-detail' blog.pk %}">{{ blog }}</a> </h6> </div> </div> <hr> {% endfor %}
内容的提问来源于stack exchange,提问作者nikalinov
相关产品推荐
相关产品推荐

