【问题标题】:Django - filter queryset disregarding spacesDjango - 过滤查询集而不考虑空格
【发布时间】:2015-04-30 07:18:06
【问题描述】:

我有一个模型,其中包含电话号码 external_number,存储为 char 字段:

models.py

class PhoneRecord(models.Model):
    def __unicode__(self):
        return "Call to %s (%s)" % (self.external_number, self.call_date.strftime("%c"))

    INBOUND = "I"
    OUTBOUND = "O"
    DIRECTION_CHOICES = (
        (INBOUND, "Inbound"),
        (OUTBOUND, "Outbound"),
    )
    external_number = models.CharField(max_length=20)
    call_date = models.DateTimeField()
    external_id = models.CharField(max_length=20)
    call_duration = models.TimeField()
    call_direction = models.CharField(max_length=1, choices=DIRECTION_CHOICES, default=INBOUND)
    call = models.FileField(upload_to='calls/%Y/%m/%d')

表单正在使用来自https://github.com/g1smd/django-localflavor-UK-forms/blob/master/django/localflavor/uk/forms.pyUKPhoneNumberField 清理和存储数据

这意味着该号码以 01234 567890 的格式存储在数据库中,即其中有一个空格。

我使用django-filters 创建了一个过滤器,它在搜索部分电话号码时效果很好除了,当搜索词不包含空格时它不能正确过滤。即

  • 搜索01234会返回上例的记录
  • 搜索567890会返回上例的记录
  • 搜索01234 567890会返回上例的记录
  • 搜索01234567890 返回上例的记录

现在,我可以使过滤器上的表单受到相同的限制(即 UKPhoneNumberField 作为输入屏幕,但这会导致无法搜索部分电话号码。

我还探索了使用 django-phonenumber-field 之类的东西来控制模型和表单的可能性,但是 UKPhoneNumberField 提供的验证允许我根据输入的数字类型(例如移动或地理)。

我最理想的情况是

  1. 我的过滤器会忽略用户在搜索查询中输入的空格或存储值中的任何空格。这甚至可能吗?
  2. UKPhoneNumberField 提供的验证应用到另一个字段类型,而无需分析和重写所有提供的正则表达式。
  3. 我还没有找到其他一些英国电话号码验证!

【问题讨论】:

  • 我知道这不能回答你的问题,但如果我是你,我会存储没有空格的数字,并在必要时显示它们的格式。
  • 谢谢@Selcuk - 我可能不得不走这条路。我一直在挑选UKPhoneNumberField 的代码,我可能比其他解决方案更快!

标签: regex django forms validation


【解决方案1】:

你可以设置过滤器来做这样的事情:

phone_number = "01234 567890"
parts = phone_number.split(" ")
PhoneRecord.objects.filter(
    external_number__startswith="{} ".format(parts[0]),
    external_number__endswith=" {}".format(parts[1]),
)

这样,过滤器会查找数字的前半部分和空格,然后再查找数字的后半部分和空格。唯一会返回的记录是值为“01234 567890”的记录

【讨论】:

  • 感谢@schillingt,但有两件事值得注意:我希望用户能够搜索,无论空间的位置如何:我希望他们(对于这个例子)是能够搜索3456 并返回此示例记录。另外,如果他们搜索时没有空格 (01234567890),我认为这不会找到记录?
  • 不,这不适用于搜索词 3456。如果这是绝对要求,那么您应该像 Selcuk 建议的那样将它们存储在没有空格的情况下。它会让你的生活变得更轻松,而且你可以在显示数字时随时对其进行格式化。对于没有空格的搜索,您需要规范化该搜索值,使其包含空格。
【解决方案2】:

我最终添加了一个带有field_class = UKPhoneFilter 的自定义过滤器。这意味着我无法搜索部分数字,但这已作为项目要求删除。

【讨论】:

    【解决方案3】:

    在将数据保存到数据库之前,您应该考虑对其进行规范化。 您可以只使用 django-phonenumber-field 就可以了。

    关于您的问题,您始终可以使用 django 的 regex 字段后缀来查询正则表达式。

    例如MyModel.objects.filter(myfiel__regex=r'[a-Z]+')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-08
      • 2018-12-01
      • 1970-01-01
      • 2020-08-22
      • 2019-04-15
      • 2011-09-29
      相关资源
      最近更新 更多