Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

search using django filter

Tags:

django

filter

I am trying to perform search on name and email field. For email field its giving an error "invalid literal for int() with base 10: '[email protected]'". but when I am using the user.id its giving correct result. For name field, its giving Cannot resolve keyword 'first_name' into field. How do i get it to work. Any help will be highly appreciated. my two models are:

class publication(models.Model):
    title = models.CharField(max_length=500)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    ....

class MyUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), max_length=254, 
            unique=True)
    first_name = models.CharField(_('first name'), max_length=30, 
            blank=True)
    last_name = models.CharField(_('last name'), max_length=30, 
            blank=True)
    .....

My view:

def search(request):
    result = publication.objects.all()
    query = request.GET.get("query")
    if query:
        result = result.filter(
            Q(title__icontains=query) |
            Q(user__first_name__icontains=query) |
            Q(user__email=query)
        ).distinct()
    user_filter = UserFilter(request.GET, queryset=result)

    return render(request, "search.html", {'filter': user_filter})

My filter:

class UserFilter(filters.FilterSet):
    title = filters.CharFilter(lookup_expr='icontains')
    first_name = filters.CharFilter(lookup_expr='iexact')
    user = filters.CharFilter(lookup_expr='exact')

    class Meta:
        model = publication
        fields = ['title', 'first_name', 'user']

Traceback (most recent call last):

File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django_filters/views.py", line 66, in get
    self.object_list = self.filterset.qs
  File "/usr/local/lib/python2.7/dist-packages/django_filters/filterset.py", line 214, in qs
    qs = filter_.filter(qs, value)
  File "/usr/local/lib/python2.7/dist-packages/django_filters/filters.py", line 171, in filter
    qs = self.get_method(qs)(**{'%s__%s' % (self.name, lookup): value})
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/query.py", line 781, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/query.py", line 799, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/sql/query.py", line 1260, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/sql/query.py", line 1286, in _add_q
    allow_joins=allow_joins, split_subq=split_subq,
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/sql/query.py", line 1216, in build_filter
    condition = lookup_class(lhs, value)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/lookups.py", line 24, in __init__
    self.rhs = self.get_prep_lookup()
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/fields/related_lookups.py", line 110, in get_prep_lookup
    self.rhs = target_field.get_prep_value(self.rhs)
  File "/usr/local/lib/python2.7/dist-packages/Django-1.11-py2.7.egg/django/db/models/fields/__init__.py", line 962, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: '[email protected]'
like image 599
surajitM Avatar asked Oct 17 '22 10:10

surajitM


1 Answers

If you need to filter by relation model's field you can use name argument of filed class:

class UserFilter(filters.FilterSet):
    title = filters.CharFilter(lookup_expr='icontains')
    first_name = filters.CharFilter(name='user__first_name', lookup_expr='iexact')
    user = filters.CharFilter(name='user__email', lookup_expr='exact')

See details here.

UPD

To filter full name try to implement custom method:

full_name = CharFilter(method='my_custom_filter')
def my_custom_filter(self, queryset, name, value):
    first_name, last_name = value.split()
    return queryset.filter(Q(user__first_name__icontains=first_name) | Q(user__last_name__icontains=last_name))
like image 157
neverwalkaloner Avatar answered Oct 27 '22 09:10

neverwalkaloner