【问题标题】:Django - Query EXACT string matchDjango - 查询精确字符串匹配
【发布时间】:2016-03-07 00:06:07
【问题描述】:

我的数据库中有一个具有此值的用户:

booking_id -> 25DgW

此字段在我的模型中标记为unique

booking_id = models.CharField(null=False, unique=True, max_length=5, default=set_booking_id)

但是现在当我这样查询用户时:

>>> User.objects.get(booking_id='25dgw')  # I think this should throw a DoesNotExist exacption
<User: John Doe>

即使我这样做:

>>> Partner.objects.get(booking_id__exact='25dgw')
<User: John Doe>

我需要一个查询,仅当代码的编写方式与保存在数据库中的方式完全相同时才返回用户:25DgW 而不是25dgw

我应该如何查询?

【问题讨论】:

  • 万一你不确定,这是mysql的问题。使用 ORM 实现这一点并不容易。原始 sql 可能会这样做:stackoverflow.com/questions/7857669/mysql-case-sensitive-query
  • @ShangWang 那么__exact 是干什么用的?有什么方法(困难且不容易)做到这一点?
  • 将您的 mysql 排序规则更改为区分大小写的排序规则。 __exact 表示 Django 应该告诉数据库您想要完全匹配。数据库排序规则设置数据库是否应考虑 'bob' 和 'Bob' 完全匹配。 stackoverflow.com/questions/5629111/… 展示了一些方法来做到这一点,但这是一个很大的话题。
  • @PeterDeGlopper 我一直在查看我的架构,发现它使用latin1 排序规则,但latin1_general_cs 可用,是否可以更改?
  • 检查如果您手动运行选择会发生什么 - 根据您所做的更改,它可能没有达到预期的效果。例如,我相信更改数据库排序规则会更改新表的默认排序规则,但不会影响现有表。

标签: mysql django django-orm


【解决方案1】:

User.objects.filter(booking_id='25dgw', booking_id__contains='25dgw').first() 似乎对我有用(结果=无)。 booking_id 参数用于断言正确的字母,仅此而已,booking_id__contains 用于断言区分大小写。

【讨论】:

    【解决方案2】:

    默认情况下,MySQL 不考虑字符串的大小写。将有与数据库/表或列关联的字符集和排序规则。

    字符集 latin1 的默认排序规则,即 latin1_swedish_ci,不区分大小写。您必须将排序规则类型更改为支持区分大小写比较的 latin1_general_cs

    您可以在数据库/表/列级别更改字符集/排序规则设置。

    以下步骤对我有用。

    1. 转到 MySQL 外壳

      mysql -u user -p databasename

    2. 更改表/列的字符集和排序规则

      ALTER TABLE tablename CONVERT TO CHARACTER SET latin1 COLLATE latin1_general_cs;
      
    3. 现在试试查询

      Partner.objects.get(booking_id__exact='25dgw')
      

    这会引发错误,table matching query does not exist.

    参考 - Character Sets and Collations in MySQL

    【讨论】:

      【解决方案3】:

      这似乎有效:

      qs.filter(booking_id__contains='25DgW').first()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-14
        • 2021-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多