我有这样一个模板来显示数据库中的块
<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>
数据模型:
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
我将数据检索为
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>]>
我想以['concept','code', 'read', 'action']
的任意顺序显示数据,而不是按ID
通过观察,我发现可以通过订购第二个字母来实现
In [7]: sorted(l, key=lambda item: item[1], reverse=True)
Out[7]: ['concept', 'code', 'read', 'action']
如何以这种方式对查询集进行排序?
答案 0 :(得分:3)
您可以先为每个Block
实例添加注释,然后按使用Substr
function [Django-doc]的注释进行排序,例如:
from django.db.models.functions import Substr
Block.objects.annotate(
sndchar=Substr('name', 2, 1)
).order_by('-sndchar')
作为每个Block
实例的额外奖励,将具有一个sndchar
属性,该属性是name
属性的第二个字符(仅在此查询集中)。但这并不是我认为的真正问题。如果它与另一列发生冲突,则可以对其进行重命名。
-sndchar
中的减号表示我们将以降序排序。如果要按升序排序,可以删除它。
因此,这里的排序是在数据库级别进行的,通常(显着)比在Django级别进行排序。
您还可以从第二个字符开始对字符串开头进行排序(这样,在使用 tie 的情况下,将考虑第三个字符等),通过删除length
参数,然后用除第一个字符之外的名称进行注释:
from django.db.models.functions import Substr
# This will sort on the third character in case of a tie, and so on
Block.objects.annotate(
sndchar=Substr('name', 2)
).order_by('-sndchar')
答案 1 :(得分:1)
使用Django的Conditional Expressions
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')