python - 使用 django 中的正则表达式按指定字段获取排序的查询集
问题描述
我在管理器中有以下内容:
class NullIf(Func):
template = "NULLIF(%(expressions)s, '')"
class MySiteManager(models.Manager):
def get_queryset(self):
qws = MySiteQuerySet(self.model, using=self._db).filter(
some_id=settings.BASE_SOME_ID).annotate(
# This is made for sorting by short labels as by numeric values
short_label_numeric=Cast(
NullIf(Func(
F('short_label'),
Value('^(\D+)|(\w+)'),
Value(''),
Value('g'),
function='regexp_replace')),
models.BigIntegerField())
).order_by('short_label_numeric', 'short_label')
for q in qws:
print(q.short_label, end='\n')
return qws
打印值的输出如下所示:
1 10 100 101 102 103 104 105 106 107 108 109 11 110 111 112 113 114 115 116 117 118 119 12 120 121 122 123 124 125 126 127 128 129 13 130 131 132 133 134 135 136 137 138 139 14 140 141 142 143 144 145 146 147 148 149 15 150 151 152 153 154 155 156 157 158 159 16 17 18 19 20 200c 21 22 23 24 25 26 260 261 262 263 264 265fs 266fs 267c 268c 269c 27 273c 274c 275c 276c 28 29 2c 30 302 31 32c 33c 34 35c 36 37 38 3c 4 5 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 524 6 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 7 701 702 703 704 705 706 707 708 709 710 8 801 802 803 804 805 806 807 808 809 810 9 901 902 S1 S10 S11 S12 S13 S14 S15 S16 S17 S18 S19 S2 S20 S3 S4 S5 S6 S7 S8 S9
我的问题是:如何使用输出构建查询集,例如 1 2 3 3c 4 5 6 6c ... 264 265fs 266fs 267c 268c 269c ... S1 S2 S3 S4 ??? 有人有任何假设吗?
解决方案
主要思想是按数字排序,然后按标签的字符部分排序,我无法复制和测试,但解决方案可能如下所示:
首先这里是sql:
SELECT
(regexp_matches(short_label, '^\d+'))[1]::numeric AS ln,
regexp_matches(short_label, '^\D+') as ls,
short_label
FROM YOUR_APP_TABLENAME ORDER BY 1, 2, 3;
orm中的注释:
对于第一个 sql 条件,我创建自定义 Func
In [1]: from myapp.models import *
In [2]: from django.db.models import F, Func, Value
...:
...: class StartNumeric(Func):
...: function = 'REGEXP_MATCHES'
...: template = "(%(function)s(%(expressions)s, '^\d+'))[1]::int"
...:
...: qs = Ingredient.objects.annotate(
...: ln=StartNumeric('short_label'),
...: ls=Func('short_label', Value('^\D+'), function='regexp_matches'),
...: ).values('ln').order_by('ln', 'ls', 'short_label')
...:
...:
In [3]: print(qs.query)
SELECT (REGEXP_MATCHES("myapp_ingredient"."short_label", '^\d+'))[1]::int AS "ln" FROM "myapp_ingredient" ORDER BY "ln" ASC, regexp_matches("myapp_ingredient"."short_label", ^\D+) ASC, "myapp_ingredient"."short_label" ASC
In [4]: data = qs.values_list('short_label', flat=True)
...: print(list(data))
...:
...:
['1', '2c', '3c', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32c', '33c', '34', '35c', '36', '37', '38', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '200c', '260', '261', '262', '263', '264', '265fs', '266fs', '267c', '268c', '269c', '273c', '274c', '275c', '276c', '302', '501', '502', '503', '504', '505', '506', '507', '508', '509', '510', '511', '512', '513', '514', '515', '516', '517', '518', '519', '520', '521', '522', '524', '601', '602', '603', '604', '605', '606', '607', '608', '609', '610', '611', '612', '613', '614', '615', '616', '617', '618', '619', '620', '621', '622', '623', '701', '702', '703', '703', '704', '705', '706', '707', '708', '709', '710', '801', '802', '803', '804', '805', '806', '807', '808', '809', '810', '901', '902', 'aaaa', 'ddd', 'ddeee', 'rrrrr', 'S1', 'S10', 'S11', 'S12', 'S13', 'S14', 'S15', 'S16', 'S17', 'S18', 'S19', 'S2', 'S20', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 'S9', 'vvvv', 'zzzz']
希望有帮助
推荐阅读
- excel - 另存为 PDF,用户可以更改默认文件名
- r - 在shinyapps上部署应用程序时目录问题
- python - 检查两个不同大小的熊猫数据框中两列的条件
- postgresql - postgreSQL 已关闭,但 pg_checksums 仍然说必须关闭集群
- ms-word - 如何在 MS Word 参考书目中显示 ISBN
- c# - Quartz C# 不同的类
- sql-server - Entity Framework 5 或 6 是否支持 SQL Server 同义词?
- linux - Git pathspecs linux(wsl)和windows之间的行为差异
- python - python中的条件切片
- java - 列表上的 Java 分页