以任意顺序对查询集进行排序

Alg*_*bra 2 python django

我有这样一个模板来呈现数据库中的块

<div class="panel panel-default">
  <div class="panel-heading">
    <a style='font-size:18pt' href="article/list/{{ b.id }}">{{ b.name }}</a>
    <span class='pull-right'>{{ b.admin }}</span>
  </div>
  <div class="panel-body">
    {{ b.desc }}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

数据模型:

class Block(models.Model):
    STATUS = (
        (1,  'normal'),
        (0, 'deleted'),
    )
    name = models.CharField("block name", max_length=100)
    desc = models.CharField("block description", max_length=100)
    admin = models.CharField("block admin", max_length=100)
    status = models.IntegerField(choices=STATUS)

    class Meta:
        ordering = ("id",)

    def __str__(self):
        return self.name   
Run Code Online (Sandbox Code Playgroud)

我检索数据为

In [2]: from article.models import Block
In [3]: blocks = Block.objects.all()
In [4]: blocks
Out[4]: <QuerySet [<Block: Concepts>, <Block: Reading>, <Block: Coding>, <Block: Action>]>
Run Code Online (Sandbox Code Playgroud)

我想以任意顺序 ['concept','code', 'read', 'action']而不是按 id 呈现数据,

通过观察,我发现这可以通过排序第二个字母来实现,

In [7]: sorted(l, key=lambda item: item[1], reverse=True)
Out[7]: ['concept', 'code', 'read', 'action']
Run Code Online (Sandbox Code Playgroud)

如何以这种方式对查询集进行排序?

Arp*_*ngh 5

使用 Django 的条件表达式

from django.db.models import Case, IntegerField, Value, When

array = ['concept', 'code', 'read', 'action']

Block.objects.annotate(
    rank=Case(
        *[When(name=name, then=Value(array.index(name))) for name in array],
        default=Value(len(array)),
        output_field=IntegerField(),
    ),
).order_by('rank')
Run Code Online (Sandbox Code Playgroud)