[Django][DRF] 如何从 .filter 获取未排序的查询集?

[Django][DRF] How to get UNORDERED queryset from `.filter`?

首先,我不是 ENG 的本地人,所以请耐心等待我的 ENG 技能或给我一些建议。

(仅供参考,Django ver 3.2.9 & DRF ver 3.12.4 with postgres ver 12.7)

我正在编写 API 通过使用 drf 序列化程序创建一个 post。我一直面临“添加到 post 的标签顺序”的问题。

这意味着,假设我在 post 上添加了标签 a、b 和 c。我使用的逻辑如下。

# class Serializer
# def create(instance):
# instance : specific post instance

tags = ['t', 'a', 'g', 's']
Tag.objects.bulk_create([Tag(name = tag) for tag in tags])
instance.tags.add(*[tag for tag in Tag.objects.filter(name__in = tags)])

运行先这样。标签按此顺序添加

TagQuerySet[Tag<'t'>, Tag<'a'>, Tag<'g'>, Tag<'s'>]

我的 API 接受了另一个包含现有标签的创建请求,

tags = ['g', 'a', 's']

django按照排序的顺序添加,不是我想要的顺序,

# tags new created instance
TagQuerySet[Tag<'a'>, Tag<'g'>, Tag<'s'>]

我知道使用 for 循环在我的列表顺序后添加标签的方法

for tag in tags:
    instance.tags.add(Tag.objects.get(name=tag))

但效率不高

所以我的问题是

您可以向标记 class 添加另一列,即优先级,每当您插入行时添加值的优先级。

然后您可以像这样按优先顺序排序:

tags = [('t', 4), ('a', 2), ('g', 1), ('s', 3)]
Tag.objects.bulk_create([Tag(name = tag[0], priority=tag[1]) for tag in tags])

Tag.objects.all().order_by('priority')

也是这个的优化版本:

for tag in tags:
    instance.tags.add(Tag.objects.get(name=tag))

这是:

tags_db = Tag.objects.filter(name__in=[tag for tag in tags])
instance.tags.set(list(tags_db))

编辑:

使用 python 排序:

my_order_list = ['g', 'a', 's', 't']
sorted(Tag.objects.all(), key=lambda x: my_order_list.index(x.name))

使用 sql 个大小写表达式排序:

Tag.objects.raw("
   SELECT * FROM Tag ORDER BY 
       CASE name
         WHEN 'g' THEN 1
         WHEN 'a' THEN 2
         WHEN 's' THEN 3
         ELSE 4 
       END
")