Python 按字母顺序比较字符串django db

Python 按字母顺序比较字符串django db,python,django,postgresql,django-models,Python,Django,Postgresql,Django Models,我有以下型号: 类页面(模型): book=外键(book,on_delete=级联) 页面=整型字段() start=CharField(最大长度=350,分贝索引=True) end=CharField(最大长度=350,分贝索引=True) 如何查询数据库以获取“包含”给定单词的页面 page1=Page.objects.create(start='beaver',end='brother') page2=Page.objects.create(start='boy',end='brot

我有以下型号:

类页面(模型):
book=外键(book,on_delete=级联)
页面=整型字段()
start=CharField(最大长度=350,分贝索引=True)
end=CharField(最大长度=350,分贝索引=True)
如何查询数据库以获取“包含”给定单词的页面

page1=Page.objects.create(start='beaver',end='brother')
page2=Page.objects.create(start='boy',end='brother')
  • Page.objects.filter(“乳房”位于开始和结束之间)应返回第1页和第2页
  • Page.objects.filter(“beast”介于开始和结束之间)不应返回任何内容
  • Page.objects.filter(“开始和结束之间的块”)应返回唯一的页面1,因为
    block
    按字母顺序排列在beaver之后和brother之前
搜索应该不区分大小写

from django.contrib.postgres.field import CICharField

class Page(Model):
      book = ForeignKey(Book, on_delete=CASCADE)
      page = IntegerField()
      start = CICharField(max_length=350, db_index=True)
      end = CICharField(max_length=350, db_index=True)

因此,我需要编写一个获取所有行的查询,其中
start
按字母顺序比给定单词“小”,而
end
按字母顺序比给定单词“大”。

您可以将
end
start
转换为小数

在您的模型中,使用
DecimalField
而不是
CharField

然后你可以使用ascii表来转换你的单词

例如,“爱”可以翻译为: 108 111 118 101

因此,在数据库中,它应该具有以下值: 0.108111118101(值应小于1,以便字的长度不会与过滤混淆)

“爱”可以翻译为: 97 109 111 117 114

请注意,“a”的ascii码只有2个数字,所有字母的位数必须相同(此处为3),因此,如果是这种情况,请将其填充为0: 0.097109111117114

然后使用小于(lt)和大于(gt)查询小数点是否介于两者之间就很容易了

注意事项:

  • 您可以使用模型的getter和setter将单词转换为ascii值,反之亦然

  • 将单词转换为小写,否则它将无法与ascii表一起使用,例如“C”的值与“C”的值不同

  • 使用ascii表格无法处理拉丁字母表中没有的内容。例如,SU.,EY,Y,Ei,,可能会破坏搜索,你应该考虑建立自己的表,或者用他们的基本字母替换这些字母…< /P>
现在让我们看看“django”是否介于“爱”和“爱”之间:


是的:)

一个选项是在保存之前将
开始
结束
的所有数据库值转换为大写或小写。然后使用过滤器
\uu gte
\uu lte
(将搜索词转换为大写或小写后)进行搜索

它似乎适合我(使用
python3.6
Django 2.2
postresql10
):

#使用小写单词创建
Page.objects.create(start='beaver',end='brother')
Page.objects.create(start='boy',end='brother')
#过滤器也使用小写字母
v=request.GET.GET('search_term','').lower()
qs=Page.objects.filter(start\u lte=v,end\u gte=v)

还是我误解了你的问题?

我的回答只适用于Postgresql,但这里可能有一个解决方案:

Django with postgresql在
Django.contrib.postgres.fields
中有一个
CICharField
模型字段。这也支持对不区分大小写的字符串进行索引。字符串仍将以正确的大小写存储,但比较操作不区分大小写

from django.contrib.postgres.field import CICharField

class Page(Model):
      book = ForeignKey(Book, on_delete=CASCADE)
      page = IntegerField()
      start = CICharField(max_length=350, db_index=True)
      end = CICharField(max_length=350, db_index=True)
这应该可以解决您的问题,您将能够使用
gte
lte
过滤器,并且比较不区分大小写。根据数据库中的设置,它应该可以很好地处理unicode

t1 = "breast"
t2 = "beast"
t3 = "block"
page1 = Page.objects.create(start='beaver', end='brother')
page2 = Page.objects.create(start='boy', end='brother')
Page.objects.filter(start__lte=t1, end__gte=t1)  # <QuerySet [<Page: Page start=beaver, end=brother>, <Page: Page start=boy, end=brother>]>
Page.objects.filter(start__lte=t2, end__gte=t2)  # <QuerySet []>
Page.objects.filter(start__lte=t3, end__gte=t3)  # <QuerySet [<Page: Page start=beaver, end=brother>]>

t4 = "Ù"  # Between Ø and Ú
t5 = "Ü"  # Not between Ø and Ú
page3 = Page.objects.create(start='Ø', end='Ú')
Page.objects.filter(start__lte=t4, end__gte=t4) # <QuerySet [<Page: Page start=Ø, end=Ú>]>
Page.objects.filter(start__lte=t5, end__gte=t5) # <QuerySet []>
t1=“乳房”
t2=“野兽”
t3=“块”
page1=Page.objects.create(start='beaver',end='brother')
page2=Page.objects.create(start='boy',end='brother')
Page.objects.filter(start_ulte=t1,end_ugte=t1)#
Page.objects.filter(start_ulte=t2,end_ugte=t2)#
Page.objects.filter(start_ulte=t3,end_ugte=t3)#
t4=“Ù”#介于Ø和Ú之间
t5=“Ü”#不在Ø和Ú之间
page3=Page.objects.create(start='Ø',end='Ú')
Page.objects.filter(start_ulte=t4,end_ugte=t4)#
Page.objects.filter(start_ulte=t5,end_ugte=t5)#

此更改将生成一个迁移,该迁移将在数据库上安装
CITextExtension()
,并更改列。您可能需要将该迁移文件分为两个迁移,第一个迁移将安装
CITextExtension
,第二个迁移将修改现有列。

breast
block
可能存储在db?@shafik@andrewcount我认为字符串的顺序是由postgres COLLATE设置定义的,而不是由Django定义的;在这个类似的问题@Andrewount中阅读更多关于它的信息。您是否有一个具体的例子在过滤时给出错误的结果?启动Python,键入
0.100106097110103111==0.100106097110103110
。答案是
True
,尽管我输入了两个不同的数字(最后一个数字不同)。把它放回这些数字所代表的原始文字:“django”和“djangn”是一样的。这里的要点是,对于试图采用这种方法的人来说,数字精度的限制将是一个问题。在数据库端和Python端都需要考虑精度问题,因为这两方面都可能出现问题。如果将字符数组保持为字符串,然后比较两者,这种方法就可以工作。对于此操作(amour'097109111117114'结果将为
True
@Louis如果我错了,请更正我,但在这种情况下,它仅取决于数据库。django决不会放弃