首页 > 解决方案 > Django 按最旧或最新的下拉菜单排序

问题描述

我正在 Django 中创建一个博客项目,并且我有以下 Post 模型:

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.pk})

我有一个显示所有帖子的页面。目前,帖子从最新到最旧列出。这是视图:

class PostListView(ListView):
    model = Post
    context_object_name = 'posts'
    ordering = ['-date_posted']

我想允许人类用户通过升序或降序对帖子进行排序(即排序)date_posted。为了提供此功能,在我列出帖子的页面顶部,我想为用户提供一个下拉菜单,其中包含两个选项:“最新”和“最旧”。选择其中一个选项应该会更改帖子的显示顺序。

我该怎么做呢?

标签: djangodjango-viewsdjango-templates

解决方案


一种选择是您可以通过 AJAX 执行此操作:

from django.http import JsonResponse
    def post_ordering_api(request):
          data = {}
          if request.GET.get('ordering', None) is not None:
              order = request.GET.get('ordering')
              if order == 'newest':
                  data['results'] = [post for post in Post.objects.filter.all().order_by('-date_posted')]
              elif order == 'oldest':
                   data['results'] = [ post for post in  Post.objects.filter.all().order_by('date_posted')]
              ...
          if request.is_ajax():
             return JsonResponse(data)
          else:
             return HttpResponseBadRequest()

在您的模板中:

 <select name="order_dropdown" id="targetDropdown">
     <option value="newest">Newest</option>
     <option value="oldest">Oldest</option>
 </select>

<div id="myDivContent">
     ...
 </div>

 <script type="text/javascript">
$("#targetDropdown").change(function(){
    var selected_value = $("#targetDropdown").val();
    $.ajax({ url: '{% url 'post_ordering_api' %}?ordering=' + selected_value,
                        type: "GET",
                        dataType: "json",
                        cache: false
               }).done(function(data) {
                    var myDiv = $('#myDivContent');
                    myDiv.empty();
                    for(i=0;i<data.results.length,i++){
                        // append results to the div html
                         myDiv.append("<p>" + data.results[i].title + "</p>");
                       }
                   }
               });
          });
</script>

可能也有完全在 JavaScript 中完成此操作的方法,但这是我想到的。一种更简单的方法是使用 Datatable,这样您就不必调用任何 AJAX 函数来进行排序,这一切都通过 JavaScript 完成。以下是相关文档: https ://datatables.net/


推荐阅读