簡體   English   中英

根據選擇字段中的值對 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

*我需要的返回值是 QuerySet 而不是排序列表。 *qs 需要根據狀態值按照'yes'、'no'、'not_sure'的順序進行排序。

請注意:我需要基於對象屬性值(即狀態值)的 thr QS。 按照 status='yes' 的順序對象先是 'no' 和 'not_sure'

鑒於之前的 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))

但是,我寧願讓數據庫來代替。 看看這個 QA有一個很好的技巧:

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

將上面的 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)

它應該可以工作,前提是 sql 中沒有order by子句。 我還沒有測試過。

更新較新的 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