如何在django中按列表进行过滤 [英] How can filter by list in django

查看:105
本文介绍了如何在django中按列表进行过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过列表过滤一个查询器
我正在通过

category = request.GET.getlist(category')
打印类型(类别)



data = Leads.objects.filter (item_required__id = category)

然后我收到错误

 基数为10的int()的无效字面值:'1,4'

那么我如何解决这个问题。

 追溯:
文件/ home / cp / Documents / envMyShopUp / local / lib / python2.7 / site-packages / django / core / handlers / base.pyin get_response
132. response = wrapped_callback(request,* callback_args,** callback_kwargs)
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/views/decorators/csrf.py在wrapped_view
58. return view_func(* args, ** kwargs)
文件/home/cp/Documents/myshopup/markatix/customapi/vendors.py在Custome rRequirements
365. cust_leads = CustomerLeads.objects.filter(item_required__id__in = category).values('customer_name','budget','event','posting_date','quantity','other','fb_id' 'image','title')。order_by(' - posting_date')
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/manager .pyin manager_method
127. return getattr(self.get_queryset(),name)(* args,** kwargs)
文件/ home / cp / Documents / envMyShopUp / local / lib / python2 .7 / site-packages / django / db / models / query.pyin filter
679. return self._filter_or_exclude(False,* args,** kwargs)
文件/ home / cp /文件/ envMyShopUp / local / lib / python2.7 / site-packages / django / db / models / query.pyin _filter_or_exclude
697. clone.query.add_q(Q(* args,** kwargs))
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/sql/query.py在add_q
1310.子句,require_inner = self._add_q(where_part,self.used_aliases)
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/sql/query。 py在_add_q
1338. allow_joins = allow_joins,split_subq = split_subq,
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models /sql/query.py在build_filter
1209. condition = self.build_lookup(lookups,col,value)
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/ build_lookup
1102. return final_lookup(lhs,rhs)
文件/ home / cp / Documents / envMyShopUp / local / lib / __init__
中的python2.7 / site-packages / django / db / models / lookups.py。self.rhs = self.get_prep_lookup()
文件/ home / cp / Documents / envMyShopUp /在get_prep_lookup
143.返回self.lhs.output_field.get_prep_lookup local / lib目录/ python2.7 /站点包/ Django的/ DB /模型/ lookups.py( self.lookup_name,self.rhs)
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/fields/__init__.pyin get_prep_lookup
729. return [self.get_prep_value(v)for v in value]
文件/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models /fields/__init__.pyin get_prep_value
985. return int(value)

例外类型:Valueapi at / customapi / vendor / customer-requirements /
异常值:无效int()与基数10的文字:'1,4'

提前感谢。 >

解决方案

可以也使用 QueryDict.getlist 来解决查询参数列出了您的请求:

  from django.http.request import QueryDict 

query = QueryDict('catego ry = 1& category = 2')
categories = query.getlist('category')# - > ['1','2']
leads = Leads.objects.filter(item_required__id__in = categories)

这样,用户可以通过在查询中逐个添加来为您提供类别列表。



然而,您的用户(或您)可能希望提供免费的样式列表,他们可能会在你的查询中是多个。在这种情况下,您必须获取所有列表,可以是主键列表,并将其映射到可在Django过滤器中使用的平面列表...

  from itertools import chain 
from django.http.request import QueryDict

query = QueryDict('categories = 1,2,3& categories = 4,5')
categories_strings = query.getlist('categories')# - > ['1,2,3','4,5']
categories = list(chain.from_iterable(
map(lambda categories:categories.split(','),categories_strings))
)# - > ['1','2','3','4','5']
leads = Leads.objects.filter(item_required__id__in = categories)
pre>

幸运的是,我们可以轻松地将其写入一个整洁的小功能:

 code>#你的myapp / utils.py模块
来自itertools import chain

#Python 3.5+类型注释函数,你可以使用
#这个没有类型Python 2.7中的注释以及
def get_query_list(querydict:QueryDict,key:str) - >列表:
返回列表(chain.from_iterable(
map(lambda query:query.split(','),querydict.getlist(key)))

这是如何工作的:

 从django.http.request导入QueryDict 
from myapp.utils import get_query_list

q = QueryDict('a = 1& a = 2& a = 3,4')
get_query_list(q,'a')# - > ['1','2','3','4']

你可以使用它从您的看法:

 #myapp.utils中的myapp / views.py模块
import get_query_list

def my_view(request):
categories = get_query_list(request.GET,'categories')#或'category'
#...

这是更详细的方式,而不是使用单一查询参数代替列表,并支持多种不同格式。



根据需要添加类型分类:

  def my_view(request):
#和整齐的单行
类别= get_query_list(request.GET,'categories')#或'category'
类别中的项目:
try:
assert int(item)
除了ValueError:
raise ValidationError('{}不正确的类型{}'。format(item,int))
#一切都应该被解析和验证
lead = Leads.objects.filter(item_required__id__in = categories)

Django在实现时经常需要这种方法搜索或通用过滤器。


I am trying to filter a queryset by a list I am getting unicode data into format of 1,4,5,6 by

category = request.GET.getlist(category')
print type(category)



data = Leads.objects.filter(item_required__id= category ) 

then i am getting a error

invalid literal for int() with base 10: '1,4'

So how can i fix this.

Traceback:
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)
File "/home/cp/Documents/myshopup/markatix/customapi/vendors.py" in CustomerRequirements
  365.      cust_leads = CustomerLeads.objects.filter(item_required__id__in= category ).values('customer_name','budget','event','posting_date','quantity','other','fb_id','image','title').order_by('-posting_date')
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/query.py" in filter
  679.         return self._filter_or_exclude(False, *args, **kwargs)
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/query.py" in _filter_or_exclude
  697.             clone.query.add_q(Q(*args, **kwargs))
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in add_q
  1310.         clause, require_inner = self._add_q(where_part, self.used_aliases)
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in _add_q
  1338.                     allow_joins=allow_joins, split_subq=split_subq,
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in build_filter
  1209.             condition = self.build_lookup(lookups, col, value)
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/sql/query.py" in build_lookup
  1102.                 return final_lookup(lhs, rhs)
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/lookups.py" in __init__
  105.         self.rhs = self.get_prep_lookup()
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/lookups.py" in get_prep_lookup
  143.         return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs)
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py" in get_prep_lookup
  729.             return [self.get_prep_value(v) for v in value]
File "/home/cp/Documents/envMyShopUp/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py" in get_prep_value
  985.         return int(value)

Exception Type: ValueError at /customapi/vendor/customer-requirements/
Exception Value: invalid literal for int() with base 10: '1,4'

Thanks in advance.

解决方案

You can also use the QueryDict.getlist to resolve query parameter lists for your request:

from django.http.request import QueryDict

query = QueryDict('category=1&category=2')
categories = query.getlist('category')  # -> ['1', '2']
leads = Leads.objects.filter(item_required__id__in=categories)

This way user can supply you a list of categories by adding them one-by-one into the query. This solution might be good enough for you.

However, your user (or you) might want to supply free style lists, and they might be multiple in your queries. In that case you would have to get all lists, which can be lists of primary keys, and map them to a flat list which can be used in a Django filter...

from itertools import chain
from django.http.request import QueryDict

query = QueryDict('categories=1,2,3&categories=4,5')
categories_strings = query.getlist('categories')  # -> ['1,2,3', '4,5']
categories = list(chain.from_iterable(
    map(lambda categories: categories.split(','), categories_strings))
)  # -> ['1', '2', '3', '4', '5']
leads = Leads.objects.filter(item_required__id__in=categories)

Luckily for us, you could easily write this into a neat little function:

# Your myapp/utils.py module
from itertools import chain

# Python 3.5+ type type annotated function, you can use
# this without the type annotations in Python 2.7 as well
def get_query_list(querydict: QueryDict, key: str) -> list:
    return list(chain.from_iterable(
        map(lambda query: query.split(','), querydict.getlist(key)))
    )

And this is how it works:

from django.http.request import QueryDict
from myapp.utils import get_query_list

q = QueryDict('a=1&a=2&a=3,4')
get_query_list(q, 'a')  # -> ['1', '2', '3', '4']

You can use it from your view:

# Your myapp/views.py module
from myapp.utils import get_query_list

def my_view(request):
    categories = get_query_list(request.GET, 'categories')  # or 'category'
    # ...

This is the more verbose way instead of using a singular query parameter in place of a list and supports multiple different formats.

Add type assortions as necessary:

def my_view(request):
    # A nice and neat one-liner
    categories = get_query_list(request.GET, 'categories')  # or 'category'
    for item in categories:
        try:
            assert int(item)
        except ValueError:
            raise ValidationError('{} is not of correct type {}'.format(item, int))
    # Everything should be parsed and validated
    leads = Leads.objects.filter(item_required__id__in=categories)

This approach is often needed with Django when implementing search or generic filters.

这篇关于如何在django中按列表进行过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆