简体   繁体   English

根据选择字段中的值对 Django 查询集进行排序

[英]Sort a Django queryset based on the values in the choice field

I have a model,我有一个模型,

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')

I need to get the query set sorted in the get_queryset method, ie,我需要在 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

*The return value i need is a QuerySet not a sorted list. *我需要的返回值是 QuerySet 而不是排序列表。 *The qs need to be sorted based on the the status value according to the order 'yes', 'no', 'not_sure'. *qs 需要根据状态值按照'yes'、'no'、'not_sure'的顺序进行排序。

Please Note: I need thr QS based on the object attribute value(ie, status value).请注意:我需要基于对象属性值(即状态值)的 thr QS。 In the order objects of status='yes' first followed by 'no' and 'not_sure'按照 status='yes' 的顺序对象先是 'no' 和 'not_sure'

Given this previous SO Q/A鉴于之前的 SO Q/A

and keeping your code, I'd say并保留你的代码,我会说

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))

However, I'd rather have the DB do it instead.但是,我宁愿让数据库来代替。 Have a look at this QA for a nice trick:看看这个 QA有一个很好的技巧:

ORDER BY idx(array['yes', 'no', 'not_sure'], status)

Add the SQL fragment above to the query generated by django's ORM (or create one ex-novo) and perform a raw query with it:将上面的 SQL 片段添加到 django 的 ORM 生成的查询中(或创建一个 ex-novo)并使用它执行原始查询

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)

It should work, provided there is no order by clause already in the sql.它应该可以工作,前提是 sql 中没有order by子句。 I haven't tested it yet.我还没有测试过。

Update for newer Django versions (tested in v3.0.10), without custom SQL syntax, using conditional expressions :更新较新的 Django 版本(在 v3.0.10 中测试),没有自定义 SQL 语法,使用条件表达式

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)
                          )
                    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM