python - 在 Django ListView 中更新 get_queryset 后如何更改排序?
问题描述
我有一个列表视图,在其中实现了搜索栏功能,但似乎我的排序现在不起作用。我该如何解决?我希望能够在方法之后以我想要的方式订购列表get_queryset
..
class MemoListView(LoginRequiredMixin, ListView):
model = Memo
template_name = 'memos/memos.html'
context_object_name = 'memos'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['memo_list'] = Memo.objects.all()
return context
def get_ordering(self):
ordering = self.request.GET.get('ordering', '-date_time')
return ordering
def get_queryset(self):
query = self.request.GET.get('q')
if query:
memo_list = Memo.objects.filter(
Q(title__icontains=query) | Q(content__icontains=query))
else:
memo_list = Memo.objects.all()
return memo_list
解决方案
如果您查看 ListView 的源代码,您会看到这样的类。
class MultipleObjectMixin(ContextMixin):
"""A mixin for views manipulating multiple objects."""
allow_empty = True
queryset = None
model = None
paginate_by = None
paginate_orphans = 0
context_object_name = None
paginator_class = Paginator
page_kwarg = 'page'
ordering = None
def get_queryset(self):
"""
Return the list of items for this view.
The return value must be an iterable and may be an instance of
` QuerySet` in which case `QuerySet` specific behavior will be enabled.
"""
if self.queryset is not None:
queryset = self.queryset
if isinstance(queryset, QuerySet):
queryset = queryset.all()
elif self.model is not None:
queryset = self.model._default_manager.all()
else:
raise ImproperlyConfigured(
"%(cls)s is missing a QuerySet. Define "
"%(cls)s.model, %(cls)s.queryset, or override "
"%(cls)s.get_queryset()." % {
'cls': self.__class__.__name__
}
)
ordering = self.get_ordering()
if ordering:
if isinstance(ordering, str):
ordering = (ordering,)
queryset = queryset.order_by(*ordering)
return queryset
def get_ordering(self):
"""Return the field or fields to use for ordering the queryset."""
return self.ordering
在您的代码中,您将覆盖 get_ordering() 以提供您想要的排序。但是您还覆盖了调用 get_ordering() 的 get_queryset() 方法。如果您没有覆盖 get_queryset() 方法,您的排序将被默认的 get_queryset() 方法接受。但是由于您要覆盖 get_queryset() 方法,因此您已明确使用 get_ordering() 方法。
通过做这样的事情来改变你的 get_queryset() 。
def get_queryset(self):
query = self.request.GET.get('q')
if query:
memo_list = Memo.objects.filter(
Q(title__icontains=query) | Q(content__icontains=query))
else:
memo_list = Memo.objects.all()
ordering = self.get_ordering()
memo_list = memo_list.order_by(ordering)
# The following checks are not needed since your get_ordering() will always only return ONE string
# if ordering and isinstance(ordering, str):
# ordering = (ordering,)
# memo_list = memo_list.order_by(*ordering)
return memo_list
推荐阅读
- r - 从单独的列 R 中获取最新的月份和年份
- kubernetes - 如何获取在给定时间范围内处于活动状态的 AKS 中的 pod 数量
- postgresql - 我在 heroku npm deploy 上不断收到 postgrator-cli 错误
- c# - 使用 Selenium 进行编程以使用 c# 和 Visual Studio 2019 自动化 ARIA:Listbox
- excel - 带有“我”关键字的 Excel VBA 切换按钮参考
- r - Caret:如何通过网格搜索找到最好的 mtry 和 ntree
- pytorch - Torch 抛出 RuntimeError: element 0 of tensors does not require grad... 但找不到计算图在哪里被切断
- javascript - 根据最后一个表单元素的选择显示隐藏 Html 表单元素
- arrays - 如何删除矩阵中的空格?
- c# - EF Core 3 嵌套值转换无法翻译