Django:Admin - 基于正则表达式的排序结果

Django: Admin - order results based on regular expression

我有一个问题,我想在 Django admin 中根据字符串中的数字对模型行进行排序并忽略字母 - 比如 XX0345XX、X0346XXX、XXX0347XX。我在想我应该为此使用正则表达式。我有一个 SQL 查询 (PostgreSQL) return 是我想要的:

select * from mytable order by substring(my_field, '\d+')::int DESC

但我无法在 Django 管理 get_queryset() 中应用它来获得相同的结果。 我试过做类似的事情:

def get_queryset():
    return Model.objects.raw("select * from mytable order by substring(my_field, '\d+')::int DESC")

但问题是我没有return这样输入正确的类型。 Model.objects.raw('...') returns RawQuerySet,但是 get_queryset() 应该 return QuerySet 实例不是 RawQuerySet 一个,所以我做不到这边走。

关于如何解决这个问题有什么建议吗?谢谢!

您可以使用 的 .extra() 方法将原始查询集转换为查询集,请参见here

这个例子取自,

class CustomManager(manager.Manager):
    def get_queryset():
        qs = self.get_queryset()
        sql = "myapp_model_b.id IN (SELECT UNNEST(myapp_model_a.pk_values) FROM myapp_model_a WHERE myapp_model_a.id='%s')" % index_id
        return qs.extra(where=[sql])

正如@Azy_Crw4282 所指出的,您可以使用 QuerySet.extra() 到 运行 原始 SQL 查询,并且仍然将结果作为 QuerySet 返回实例。

以下是我如何根据字符串中的数字设法对管理视图中的对象执行基于 "ORDER BY" 的正则表达式。 IE。根据它们包含的数字对 XX0345XX、X0346XXX、XXX0347XX 等字段进行排序 - 基本上得到一个与 '\d+' 正则表达式匹配的子字符串。

只需覆盖 admin.ModelAdmin class 中的 get_queryset() 函数即可。

解法:

def get_queryset(self, request):
    sql_query = "CAST(substring(booking_reference, '\d+') as int)"
    bookings = Booking.objects.extra(select={'book_ref_digits': sql_query}).order_by('-book_ref_digits')
    return bookings

据我了解,它添加了一个新的临时字段,例如book_ref_digitsQuerySet 对象中,然后您可以对其执行 .order_by()

注意:使用旧版本的 Django 1.10.5