使用django过滤器搜索

时间:2017-06-29 05:54:27

标签: django filter

我正在尝试在名称和电子邮件字段上执行搜索。 对于电子邮件字段,它给出了一个错误“int(()的无效文字,基数为10:'abc@xyz.com'”。但是当我使用user.id时,它会给出正确的结果。 对于名称字段,其给定无法将关​​键字“first_name”解析为字段。 我如何让它工作。任何帮助将受到高度赞赏。 我的两个模型是:

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

我的观点:

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

我的过滤器:

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

追踪(最近一次呼叫最后一次):

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: 'abc@xyz.com'

2 个答案:

答案 0 :(得分:0)

如果您需要按关系模型的字段进行过滤,则可以使用已提交类的name参数:

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

详见here

<强> UPD

要过滤全名,请尝试实现自定义方法:

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

答案 1 :(得分:0)

我在我的 views.py 上使用表 blognews 进行案例搜索查询,此代码用于使用名称输入关键字进行表单发布方法搜索:

def list_content(request):
shelf       = content.objects.all()
if(request.method=="POST"):
    keyword=request.POST.get('keyword')
    shelf=blogsnews.objects.filter(judul__icontains=keyword)   

return render(request,'homepage/list_news.html',{'shelf':shelf})

对于函数过滤器“icontains 或 contains 请访问 docs django 手册