Django - filter queryset disregarding spaces

2019-09-06 21:13发布

I have a model that contains phone numbers external_number, stored as a char field:

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')

The form is cleaning and storing the data using the UKPhoneNumberField from https://github.com/g1smd/django-localflavor-UK-forms/blob/master/django/localflavor/uk/forms.py

This means that the number is stored in the database in the format 01234 567890 i.e. with a space in.

I have created a filter using django-filters which works well, when searching for partial phone number except that it doesn't filter correctly when the search term doesn't include the space. i.e.

  • search for 01234 returns the record for the example above
  • search for 567890 returns the record for the example above
  • search for 01234 567890 returns the record for the example above
  • search for 01234567890 does not return the record for the example above

Now, I could subject the form on the filter to the same restrictions (i.e. UKPhoneNumberField as the input screen, but that then takes away the ability to search for partial phone numbers.

I have also explored the possibility of using something like django-phonenumber-field that will control both the model and the form, but the validation provided by UKPhoneNumberField allows me to validate based on the type of number entered (e.g. mobile or geographical).

What I would ideally like is either

  1. My filter to ignore spaces that are either input by the user in their search query, or any spaces that are in the stored value. Is this even possible?
  2. Apply the validation provided by UKPhoneNumberField to another field type without having to analyse and re-write all the regular expressions provided.
  3. Some other UK Phone number validation I have not found yet!

3条回答
SAY GOODBYE
2楼-- · 2019-09-06 21:25

I ended up adding a custom filter with a field_class = UKPhoneFilter. This means I can't search on partial numbers, but that was removed as a requirement from the project.

查看更多
放荡不羁爱自由
3楼-- · 2019-09-06 21:30

You should think about normalizing the data before you save them into your DB. You could just use django-phonenumber-field which does just that.

In regarding your problem you can always use django's regex field postfix to query over regular expression.

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

查看更多
再贱就再见
4楼-- · 2019-09-06 21:41

You could setup the filter to do something like this:

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

That way the filter is looking for the first half of the number with the space and then the second half of the number with the space as well. The only records that would be returned would be ones that had the value of "01234 567890"

查看更多
登录 后发表回答