comb_filter = [
v1.FilterOption('gender',is_choice=True),
v1.FilterOption('depart'),
v1.FilterOption('roles',multi=True)
]
comb_filter = []
def get_comb_filter(self):
res = []
if self.comb_filter:
res.extend(self.comb_filter)
return res
self.comb_filter = config.get_comb_filter()
def gen_comb_filter(self):
"""
生成器函数
根据字段,获取与之关联的数据,交给FilterRow做处理
:return:
"""
"""
self.comb_filter = [
FilterRow(((1,'男'),(2,'女'),)),
FilterRow([obj,obj,obj,obj ]),
FilterRow([obj,obj,obj,obj ]),
]
"""
data_list = []
for option in self.comb_filter:
_field = self.model_class._meta.get_field(option.field_name)
from django.db.models import ForeignKey,ManyToManyField
if isinstance(_field,ForeignKey):
row = FilterRow(option,option.get_querySet(_field),self.request)
elif isinstance(_field,ManyToManyField):
row = FilterRow(option,option.get_querySet(_field),self.request)
else:
row = FilterRow(option,option.get_choices(_field),self.request)
data_list.append(row)
return data_list
- FilterOption类,用来配置作为搜索条件的字段
class FilterOption(object):
def __init__(self,field_name,multi=False,condition=None,is_choice=False):
"""
:param field_name:字段名
:param multi:是否多选
:param condition:显示数据的筛选条件
:param is_choice:字段是否是choice类型(否则为外键或多对多)
"""
self.field_name = field_name
self.multi = multi
self.condition = condition
self.is_choice = is_choice
def get_querySet(self,_field):
if self.condition:
querySet = _field.rel.to.objects.filter(**self.condition)
else:
querySet = _field.rel.to.objects.all()
return querySet
def get_choices(self,_field):
return _field.choices
- FilterRow类,它的迭代对象为页面上显示的一行条件
class FilterRow(object):
def __init__(self, option, data, request):
self.option = option
self.data = data
self.request = request # request
def __iter__(self):
params = copy.deepcopy(self.request.GET)
params._mutable = True
current_id = params.get(self.option.field_name) # 3
current_id_list = params.getlist(self.option.field_name) # [1,2,3]
if self.option.field_name in params: # 如果传来的参数中有这个字段,代表全选没有被勾中
# del params[self.option.field_name]
print(params)
origin_list = params.pop(self.option.field_name) # 删除对应字段,并记录下它的值
print(params,origin_list)
url = "{0}?{1}".format(self.request.path_info, params.urlencode())
yield mark_safe('<a href="{0}" class="">全部</a>'.format(url))
params.setlist(self.option.field_name, origin_list) # 回复原状
else: # 传来的参数中没有这个字段,代表全选被勾中
url = "{0}?{1}".format(self.request.path_info, params.urlencode())
yield mark_safe('<a class="active" href="{0}">全部</a>'.format(url))
for val in self.data:
if self.option.is_choice: # 字段是choice类型
pk, text = str(val[0]), val[1]
else: # 字段是外键或多对多类型
pk, text = str(val.pk), str(val)
# 当前URL?option.field_name
# 当前URL?gender=pk
# self.request.path_info # http://127.0.0.1:8005/arya/crm/customer/?gender=1&id=2
# self.request.GET['gender'] = 1 # &id=2gender=1
if not self.option.multi: # 单选
params[self.option.field_name] = pk
url = "{0}?{1}".format(self.request.path_info, params.urlencode())
if current_id == pk:
yield mark_safe("<a class='active' href='{0}'>{1}</a>".format(url, text))
else:
yield mark_safe("<a href='{0}'>{1}</a>".format(url, text))
else: # 多选 current_id_list = ["1","2"]
_params = copy.deepcopy(params)
id_list = _params.getlist(self.option.field_name)
if pk in current_id_list:
id_list.remove(pk)
_params.setlist(self.option.field_name, id_list)
url = "{0}?{1}".format(self.request.path_info, _params.urlencode())
yield mark_safe("<a class='active' href='{0}'>{1}</a>".format(url, text))
else:
id_list.append(pk)
# params中被重新赋值
_params.setlist(self.option.field_name, id_list)
# 创建URL
url = "{0}?{1}".format(self.request.path_info, _params.urlencode())
yield mark_safe("<a href='{0}'>{1}</a>".format(url, text))
def changelist_view(self,request):
"""
列表页面对应视图函数
"""
# 处理action
if request.method == 'POST' and self.get_show_action_list():
func_name_str = request.POST.get('list_action')
action_func = getattr(self, func_name_str)
ret = action_func(request)
if ret:
return ret
# 组合条件
comb_condition = {}
option_list = self.get_comb_filter()
for key in request.GET.keys():
value_list = request.GET.getlist(key)
flag = False
for option in option_list:
if option.field_name == key:
flag = True
break
if flag:
comb_condition["%s__in" % key] = value_list
querySet = self.model_class.objects.filter(self.get_cond_Q()).filter(**comb_condition).distinct()
cl = ChangeList(self,querySet)
return render(request, 'curd/changelist_view.html', {'cl':cl})
<style>
.list-filter a{
display: inline-block;
padding: 3px 6px;
border: 1px solid #2e6da4;
margin: 3px 0;
}
.list-filter a.active{
background-color: #2e6da4;
color: white;
}
</style>
<!----------组合条件------------------>
<div class="list-filter">
{% for item in cl.gen_comb_filter %}
<div>
{% for col in item %}
{{ col }}
{% endfor %}
</div>
{% endfor %}
</div>
网友评论