根据选择字段中的值对 Django 查询集进行排序
Sort a Django queryset based on the values in the choice field
我有模型,
class Example(models.Model):
MY_CHOICES = (
("yes", _("Yes")),
("no", _("NO")),
("not_sure", _("Not sure")),
)
name = models.CharField(max_length=200, verbose_name=_('Name'))
status = models.CharField(max_length=100,choices=MY_CHOICES,default='yes')
我需要在 get_queryset 方法中对查询集进行排序,即
def get_queryset(self, request):
qs = self.model._default_manager.get_queryset()
order = ['yes', 'no', 'not_sure']
qs = #CODE TO ORDER THE S HERE BASED ON order.
return qs
*我需要的 return 值是 QuerySet 而不是排序列表。
*qs需要根据status值按照'yes', 'no', 'not_sure'.
的顺序排序
请注意:我需要基于对象属性值(即状态值)的 QS。在 status='yes' 的顺序对象中,首先是 'no' 和 'not_sure'
给定 this previous SO Q/A
并保留您的代码,我会说
def get_queryset(self, request):
qs = self.model._default_manager.get_queryset()
order = ['yes', 'no', 'not_sure']
return sorted(qs, key=lambda x: order.index(x.status))
但是,我宁愿让数据库代替它。
看一下 this QA 的技巧:
ORDER BY idx(array['yes', 'no', 'not_sure'], status)
将上面的 SQL 片段添加到 django 的 ORM 生成的查询中(或创建一个 ex-novo)并用它执行 raw query:
def get_queryset(self, request):
qs = self.model._default_manager.get_queryset()
newquery = qs.query+' ORDER BY idx(array'+order.__str__()+', status)'
return self.model._default_manager.raw(newquery)
如果 sql 中没有 order by
子句,它应该可以工作。我还没有测试过。
更新 Django 版本(在 v3.0.10 中测试),没有自定义 SQL 语法,使用 conditional expressions:
from django.contrib import admin
from django.db.models import Case, When, Value
class ExampleAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.order_by( Case(
When ( status="yes", then=Value(0) ),
When ( status="no", then=Value(1) ),
default = Value(2)
)
)
我有模型,
class Example(models.Model):
MY_CHOICES = (
("yes", _("Yes")),
("no", _("NO")),
("not_sure", _("Not sure")),
)
name = models.CharField(max_length=200, verbose_name=_('Name'))
status = models.CharField(max_length=100,choices=MY_CHOICES,default='yes')
我需要在 get_queryset 方法中对查询集进行排序,即
def get_queryset(self, request):
qs = self.model._default_manager.get_queryset()
order = ['yes', 'no', 'not_sure']
qs = #CODE TO ORDER THE S HERE BASED ON order.
return qs
*我需要的 return 值是 QuerySet 而不是排序列表。 *qs需要根据status值按照'yes', 'no', 'not_sure'.
的顺序排序请注意:我需要基于对象属性值(即状态值)的 QS。在 status='yes' 的顺序对象中,首先是 'no' 和 'not_sure'
给定 this previous SO Q/A
并保留您的代码,我会说
def get_queryset(self, request):
qs = self.model._default_manager.get_queryset()
order = ['yes', 'no', 'not_sure']
return sorted(qs, key=lambda x: order.index(x.status))
但是,我宁愿让数据库代替它。 看一下 this QA 的技巧:
ORDER BY idx(array['yes', 'no', 'not_sure'], status)
将上面的 SQL 片段添加到 django 的 ORM 生成的查询中(或创建一个 ex-novo)并用它执行 raw query:
def get_queryset(self, request):
qs = self.model._default_manager.get_queryset()
newquery = qs.query+' ORDER BY idx(array'+order.__str__()+', status)'
return self.model._default_manager.raw(newquery)
如果 sql 中没有 order by
子句,它应该可以工作。我还没有测试过。
更新 Django 版本(在 v3.0.10 中测试),没有自定义 SQL 语法,使用 conditional expressions:
from django.contrib import admin
from django.db.models import Case, When, Value
class ExampleAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.order_by( Case(
When ( status="yes", then=Value(0) ),
When ( status="no", then=Value(1) ),
default = Value(2)
)
)