当前位置: 首页 > news >正文

django常用的组合搜索组件

文章目录

  • django常用的组合搜索组件
    • 快速使用
      • 配置信息
      • 1. 视图函数
      • 2. 前端模板
      • 3. css样式
    • 代码实现

django常用的组合搜索组件

在项目开发中,如果有大量数据就要用到组合搜索,通过组合搜索对大块内容进行分类筛选。

在这里插入图片描述

快速使用

三步走:(其实主要就是传入配置信息)

  1. 创建组合搜索类的实例对象,传入参数进行配置(三个参数: request, model_class, *options
  2. 在数据库查询时传入search_group.get_condition方法生成的查询条件(该方法会根据传入的配置生成查询条件)
  3. 在前端使用search_group.get_row_list(search_group.get_row_list生成一个列表,包含所有传入的Option字段的信息)

配置信息

这是Option类的init函数:

class Option(object):def __init__(self, field, is_condition=True, is_multi=False, db_condition=None, text_func=None, value_func=None):""":param field: 组合搜索关联的字段(支持choice/Foreignkey类型):param is_multi: 是否支持多选:param db_condition: 数据库关联查询时的条件(字典):param text_func: 此函数用于显示组合搜索按钮页面文本(页面展示的值):param value_func: 此函数用于显示组合搜索按钮值(url中的参数值)"""self.field = fieldself.is_condition = is_conditionself.is_multi = is_multiif not db_condition:db_condition = {}self.db_condition = db_conditionself.text_func = text_funcself.value_func = value_funcself.is_choice = False

示例:

search_group = NbSearchGroup(request,models.TransactionRecord,Option('charge_type', is_multi=True, text_func=lambda x: x[1],value_func=lambda x:x[0]),  # choiceOption('customer', db_condition={"id__lte": 10, 'active': 1}, text_func=lambda x: x.username,value_func=lambda x:x.id),  # fk)

在这里插入图片描述

1. 视图函数

from django.shortcuts import render
from web import models
from utils.pager import Pagination
from django.db.models import Q
from utils.group import Option, NbSearchGroupdef my_transaction_list(request):# 第一步:配置和传参search_group = NbSearchGroup(request,models.TransactionRecord,Option('charge_type'),  # choice)# ...其他的查询条件# 第二步:获取条件 .filter(**search_group.get_condition)queryset = models.TransactionRecord.objects.filter(**search_group.get_condition).filter(其他查询条件)pager = Pagination(request, queryset) # 分页组件context = {"pager": pager,"keyword": keyword,"search_group": search_group  # 第三步:将对象传入前端页面}return render(request, 'my_transaction_list.html', context)

2. 前端模板

{% if search_group.get_row_list %}<div class="panel panel-default"><div class="panel-heading"><i class="fa fa-filter" aria-hidden="true"></i> 快速筛选</div><div class="panel-body"><div class="search-group">{% for row in search_group.get_row_list %}<div class="row">{% for obj in row %}{{ obj|safe }}{% endfor %}</div>{% endfor %}</div></div></div>
{% endif %}

3. css样式

.search-group {padding: 5px 10px;
}.search-group .row .whole {width: 60px;float: left;display: inline-block;padding: 5px 0 5px 8px;margin: 3px;font-weight: bold;text-align: right;}.search-group .row .others {padding-left: 80px;
}.search-group .row a {display: inline-block;padding: 5px 8px;margin: 3px;border: 1px solid #d4d4d4;}.search-group .row a {display: inline-block;padding: 5px 8px;margin: 3px;border: 1px solid #d4d4d4;
}.search-group a.active {color: #fff;background-color: #337ab7;border-color: #2e6da4;
}

代码实现

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.db.models import ForeignKey, ManyToManyFieldclass SearchGroupRow(object):def __init__(self, title, queryset_or_tuple, option, query_dict):""":param title: 组合搜索的列名称:param queryset_or_tuple: 组合搜索关联获取到的数据:param option: 配置:param query_dict: request.GET"""self.title = titleself.queryset_or_tuple = queryset_or_tupleself.option = optionself.query_dict = query_dictdef __iter__(self):yield '<div class="whole">'yield self.titleyield '</div>'yield '<div class="others">'total_query_dict = self.query_dict.copy()total_query_dict._mutable = Trueorigin_value_list = self.query_dict.getlist(self.option.field)if not origin_value_list:yield "<a class='active' href='?%s'>全部</a>" % total_query_dict.urlencode()else:total_query_dict.pop(self.option.field)yield "<a href='?%s'>全部</a>" % total_query_dict.urlencode()for item in self.queryset_or_tuple:text = self.option.get_text(item)value = str(self.option.get_value(item))query_dict = self.query_dict.copy()query_dict._mutable = Trueif not self.option.is_multi:query_dict[self.option.field] = valueif value in origin_value_list:query_dict.pop(self.option.field)yield "<a class='active' href='?%s'>%s</a>" % (query_dict.urlencode(), text)else:yield "<a href='?%s'>%s</a>" % (query_dict.urlencode(), text)else:# {'gender':['1','2']}multi_value_list = query_dict.getlist(self.option.field)if value in multi_value_list:multi_value_list.remove(value)query_dict.setlist(self.option.field, multi_value_list)yield "<a class='active' href='?%s'>%s</a>" % (query_dict.urlencode(), text)else:multi_value_list.append(value)query_dict.setlist(self.option.field, multi_value_list)yield "<a href='?%s'>%s</a>" % (query_dict.urlencode(), text)yield '</div>'class Option(object):def __init__(self, field, is_condition=True, is_multi=False, db_condition=None, text_func=None, value_func=None):""":param field: 组合搜索关联的字段:param is_multi: 是否支持多选:param db_condition: 数据库关联查询时的条件:param text_func: 此函数用于显示组合搜索按钮页面文本:param value_func: 此函数用于显示组合搜索按钮值"""self.field = fieldself.is_condition = is_conditionself.is_multi = is_multiif not db_condition:db_condition = {}self.db_condition = db_conditionself.text_func = text_funcself.value_func = value_funcself.is_choice = Falsedef get_db_condition(self, request, *args, **kwargs):return self.db_conditiondef get_queryset_or_tuple(self, model_class, request, *args, **kwargs):"""根据字段去获取数据库关联的数据:return:"""# 根据gender或depart字符串,去自己对应的Model类中找到 字段对象field_object = model_class._meta.get_field(self.field)title = field_object.verbose_name# 获取关联数据if isinstance(field_object, ForeignKey) or isinstance(field_object, ManyToManyField):# FK和M2M,应该去获取其关联表中的数据: QuerySetdb_condition = self.get_db_condition(request, *args, **kwargs)return SearchGroupRow(title,field_object.remote_field.model.objects.filter(**db_condition),self,request.GET)else:# 获取choice中的数据:元组self.is_choice = Truereturn SearchGroupRow(title, field_object.choices, self, request.GET)def get_text(self, field_object):"""获取文本函数:param field_object::return:"""if self.text_func:return self.text_func(field_object)if self.is_choice:return field_object[1]return str(field_object)def get_value(self, field_object):if self.value_func:return self.value_func(field_object)if self.is_choice:return field_object[0]return field_object.pkdef get_search_condition(self, request):if not self.is_condition:return Noneif self.is_multi:values_list = request.GET.getlist(self.field)  # tags=[1,2]if not values_list:return Nonereturn '%s__in' % self.field, values_listelse:value = request.GET.get(self.field)  # tags=[1,2]if not value:return Nonereturn self.field, valueclass NbSearchGroup(object):""" 最后的封装应用类,使用时三步走 """def __init__(self, request, model_class, *options):self.request = requestself.model_class = model_classself.options = optionsdef get_row_list(self):row_list = []for option_object in self.options:row = option_object.get_queryset_or_tuple(self.model_class, self.request)row_list.append(row)return row_list@propertydef get_condition(self):""":return: 获取组合搜索的条件"""condition = {}# ?depart=1&gender=2&page=123&q=999for option in self.options:key_and_value = option.get_search_condition(self.request)if not key_and_value:continuekey, value = key_and_valuecondition[key] = valuereturn condition

若有错误与不足请指出,关注DPT一起进步吧!!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【区块链+金融服务】山西省信易贷平台 | FISCO BCOS应用案例
  • redis面试(九)锁重入和互斥
  • 基于PCA-BP的数据多变量回归预测 Matlab代码(多输入单输出)[可显示原始特征贡献率+贡献率排序+累计贡献率]
  • 【Git】远程仓库新建分支后,拉到本地开发
  • 音视频概要
  • 主机防火墙测试--IPV6地址TCP/UDP/ICMP协议测试方法
  • 应对FingerprintJS反爬:Selenium的破解策略与技术详解
  • 【零基础学习CAPL语法】——TestWaitForMessage:等待指定报文
  • MongoDB教程
  • Elasticsearch 桶(Bucket)聚合详解及示例
  • 基于vue框架的XXXX勤工助学管理系统vl6ft(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • Unity3D Rect Transform 组件详解
  • ffmpeg -- 常用口令
  • Keepalived + LVS实现高可用
  • 华为设备支持的逻辑接口类型及逻辑接口配置
  • [nginx文档翻译系列] 控制nginx
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • 2017 年终总结 —— 在路上
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • CSS实用技巧干货
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Python学习之路13-记分
  • 那些被忽略的 JavaScript 数组方法细节
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 学习JavaScript数据结构与算法 — 树
  • ​字​节​一​面​
  • # windows 运行框输入mrt提示错误:Windows 找不到文件‘mrt‘。请确定文件名是否正确后,再试一次
  • #stm32整理(一)flash读写
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (八)Spring源码解析:Spring MVC
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .htaccess 强制https 单独排除某个目录
  • .NET : 在VS2008中计算代码度量值
  • .net 4.0发布后不能正常显示图片问题
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .NET连接数据库方式
  • @RequestMapping-占位符映射
  • [20171106]配置客户端连接注意.txt
  • [AIGC] SQL中的数据添加和操作:数据类型介绍
  • [Android]通过PhoneLookup读取所有电话号码
  • [bzoj2957]楼房重建
  • [C#][opencvsharp]opencvsharp sift和surf特征点匹配
  • [c]统计数字
  • [CentOs7]iptables防火墙安装与设置
  • [CF482B]Interesting Array
  • [Django 0-1] Core.Checks 模块
  • [Doc][px4][ros2][gazebo][yolov8]PX4-ROS2-Gazebo-YOLOv8
  • [emuch.net]MatrixComputations(7-12)
  • [Hibernate] - Fetching strategies
  • [IE9] GPU硬件加速到底是实用创新还是噱头