2

I have a model as follows

class Person:
  name = models.CharField()
  city = models.CharField()
  phone = models.CharField()

I want to create a filter in the admin page, the filter should be based on phone, that is

valid phone(having 10 digits)
invalid phone

I don't want to create a validation. I just want to filter out who has a valid phone and invalid. Thanks

BDL
  • 21,052
  • 22
  • 49
  • 55
potato tomato
  • 47
  • 1
  • 12
  • 1
    did you look for phonenumber-field: https://github.com/stefanfoulis/django-phonenumber-field ? – Brown Bear Aug 08 '17 at 09:24
  • Or you could try something like this: https://stackoverflow.com/a/19131360/3848720 – tdsymonds Aug 08 '17 at 09:37
  • @BearBrown I didn't get you. I can create a normal filter using "list_filter" but this will bring me the whole no, instead I want to customized the filter to show me the valid phone numbers and invalid phone numbers separately. I don't want to put validation while saving it. – potato tomato Aug 08 '17 at 09:39
  • @tdsymonds I don't want to put validation. I just want to know among the saved no's which one is valid and which one isn't. I want to see this filter in the admin page – potato tomato Aug 08 '17 at 09:41
  • do you need html template filter? – Brown Bear Aug 08 '17 at 09:47
  • @BearBrown I dont know that but what I know is I want to create a filter in the admin page which will show me users with invalid phone no and valid no. Only the admin need to have this privilege – potato tomato Aug 08 '17 at 09:50

2 Answers2

6

Create a custom list filter class. There's an example in the docs which can be adopted to your case.

from django.contrib import admin

class ValidPhoneListFilter(admin.SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = _('valid phone')

    parameter_name = 'valid_phone'

    def lookups(self, request, model_admin):
        return (
            ('valid', _('valid phone')),
            ('invalid', _('invalid phone')),
        )

    def queryset(self, request, queryset):
        if self.value() == 'valid':
            return queryset.filter(phone__regex=r'^\d{10}$')
        if self.value() == 'invalid':
            return queryset.exclude(phone__regex=r'^\d{10}$')

Then include your list filter class in list_filter for your model admin.

class PersonAdmin(admin.ModelAdmin):
    list_filter = (ValidPhoneListFilter,)
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Thanks I think this will work. Let me check it out and will come back to you – potato tomato Aug 08 '17 at 10:05
  • The filter has come in the right side with option of valid and Invalid but the filter is not working as planned. Clicking valid will give no values and clicking Invalid will give all the values. I think the problem is in the regular expression. please check it once and let me know. your answer is the closest i found – potato tomato Aug 08 '17 at 12:10
  • The regex appears to be ok to me - `import re; re.search(r'^\d{10}$', '0123456789')` returns a match. – Alasdair Aug 08 '17 at 12:15
1

You could do something like

from django.core.validators import RegexValidator

phone_regex = RegexValidator(r'^[0-9]{10}$', 'Invalid phone number')

And in your model

phone = models.CharField(validators=[phone_regex])

This regex only checks if it is digits and that the length is 10. Modify it after your specific needs.

Hope this helps.

Good luck!

LanfeaR
  • 241
  • 1
  • 8