【CRM客户关系管理】13.为结果添加搜索功能,搜索后能对其进行
2018-12-04 本文已影响4人
吾星喵
个人博客,欢迎查看:https://blog.starmeow.cn/
Github地址:https://github.com/xyliurui/DjangoCRM
搜索功能
image.png
视图中创建搜索函数
在djadmin应用下的视图中创建get_search_result(request, queryset, admin_class)函数
def get_search_result(request, queryset, admin_class):
"""搜索"""
keyword = request.GET.get('_kw', '')
if keyword:
from django.db.models import Q
q = Q()
q.connector = 'OR'
for search_field in admin_class.search_fields:
q.children.append(("{}__contains".format(search_field), keyword))
print(q) # (OR: contact__contains, consultant__name__contains)
queryset = queryset.filter(q)
return queryset, keyword
详情视图中增加搜索函数
@login_required
def table_detail(request, app_name, model_name):
"""取出指定model里的数据返回到前端"""
# 拿到admin_class后,通过它获取model
admin_class = site.enable_admins[app_name][model_name]
# print(admin_class) # 执行djadmin.py定义的注册模型类
queryset = admin_class.model.objects.all()
# print(queryset)
# 进行过滤
queryset, filter_conditions = get_filter_result(request, queryset)
# 将过滤字典保存到全局注册类中
admin_class.filter_conditions = filter_conditions
# 搜索
queryset, keyword = get_search_result(request, queryset, admin_class)
admin_class.search_keyword = keyword # 将搜索字符串保存到全局类中
# 排序,返回排序的结果和排序的字段字典
queryset, current_order_field = get_order_result(request, queryset, admin_class)
# print(current_order_field) # {'consult_content': '4'}
# 如果有排序,保存排序的值,用于模板中在分页模块显示
if current_order_field.values():
current_order_value = list(current_order_field.values())[0]
else:
current_order_value = ''
# 查询集结果分页
paginator = Paginator(queryset, 10) # Show 10 contacts per page
page = request.GET.get('page')
try:
queryset = paginator.get_page(page)
except PageNotAnInteger:
queryset = paginator.get_page(1)
except EmptyPage:
queryset = paginator.get_page(paginator.num_pages)
return render(request, 'djadmin/table_detail.html', locals())
模板中的搜索框
在djadmin应用下的templates/djadmin/base.html修改搜索框参数
<form class="navbar-form navbar-right">
<input name="_kw" type="text" class="form-control" placeholder="Search..." value="{{ keyword }}">
</form>
image.png
当用户搜索后会根据注册模型中的search_fields列表进行搜索,然后返回搜索后的结果,并把关键字显示在搜索框中
过滤和搜索组合
搜索过滤后的结果
直接修改base.html模板,在搜索的表单中增加过滤的隐藏表单
<form class="navbar-form navbar-right">
<input name="_kw" type="text" class="form-control" placeholder="Search..." value="{{ keyword }}">
{% for k, v in admin_class.filter_conditions.items %}
<input type="hidden" name="{{ k }}" value="{{ v }}">
{% endfor %}
</form>
image.png
image.png
增加过滤字段提示
修改模板标签build_option_filter(filter_field, admin_class)过滤表单部分,增加爱<label>{}:</label>标签
@register.simple_tag
def build_option_filter(filter_field, admin_class):
select = "<label>{}:</label><select name='{}' class='form-control'>".format(filter_field, filter_field)
# 获取列中的字段对象
filter_field_obj = admin_class.model._meta.get_field(filter_field)
try:
for choice in filter_field_obj.get_choices(): # choice[0]为选项的值,choice[1]为选中的可见内容
# 获取过滤字典中的值,并在模板中呈选中状态
selected = ''
if filter_field in admin_class.filter_conditions:
# 如果当前值被选中
if str(choice[0]) == admin_class.filter_conditions.get(filter_field):
selected = 'selected'
option = "<option value='{}' {}>{}</option>".format(choice[0], selected, choice[1])
select += option
except AttributeError as e:
# 对时间使用单独的select
select = "<label>{}:</label><select class='form-control' name='{}__gte'>".format(filter_field, filter_field)
# print(filter_field_obj.get_internal_type()) # 这儿得到的结果是:DateField
if filter_field_obj.get_internal_type() in ('DateField', 'DateTimeField'):
import datetime
now_time = datetime.datetime.now()
filter_time_list = [
('', '所有时间'),
(now_time, '今天'),
(now_time - datetime.timedelta(7), '7天内'), # 往前7天
(now_time.replace(day=1), '本月'), # 本月内
(now_time - datetime.timedelta(90), '三个月内'),
(now_time.replace(month=1, day=1), '本年'),
]
for dt in filter_time_list:
# 如果选择的时间值不为空,则进行时间格式化
time_to_str = '' if not dt[0] else dt[0].strftime('%Y-%m-%d') # 需要将时间格式化成:YYYY-MM-DD
# 修改name后,过滤时间的参数变成了created_time__gte=2018-11-03,所以下方的选中,需要进行修改
# 设置选中
selected = ''
if filter_field + '__gte' in admin_class.filter_conditions:
# 如果当前值被选中
if time_to_str == admin_class.filter_conditions.get(filter_field + '__gte'):
selected = 'selected'
option = "<option value='{}' {}>{}</option>".format(time_to_str, selected, dt[1])
select += option
select += "</select>"
return mark_safe(select)
image.png