- 关键字搜索。 可以做到的效果是, 输入20。 后太通过 Q()  函数。 来实现。  搜索是一个大的问题点。

-  要想实现组合搜索, 首先要 明确的一点是。 在我当前的页面上, 正在进行展示的是 那一张表的数据。
- 并且, 既然是搜索, 那么必然的一点就是。 我的搜索条件, 必须是 和 我这张表中的,字段由关系的。
  - 比如, UserInfo 表。 那么 名字就是一个 可以用作搜索的字段。 年龄也是一个可以用作搜索的字段。
  - 组合搜索,就是。 将 name 和 age 这两个字段, 甚至更多的字段进行一个组合的搜索。
  -  在这个基础上, 我们可以添加上, 模糊一点的条件, 比如 age>20。

先看一下我想做的,这张表把:

class UserInfo(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(verbose_name="用户名", max_length=32)
pwd = models.CharField(verbose_name="密码", max_length=16)
age = models.CharField(verbose_name="年龄", max_length=3) depart = models.ForeignKey(verbose_name="部门", to="Depart", to_field="id", on_delete=models.CASCADE) class_choice = [
(1, "九年级一班"),
(2, "九年级二班"),
(3, "九年级三班"),
]
classes = models.IntegerField(verbose_name="班级", choices=class_choice, default=1)
gender_choice = [
(1, "男"),
(2, "女")
]
gender = models.IntegerField(verbose_name="性别", choices=gender_choice, default=1) def __str__(self):
return self.name

分析得出的结果就是。 这里有7 个字段。 id 先不考虑。 pwd 密码也不考虑。

name 字段。 使用关键字的方式, 进行模糊的查询。
age 字段可以, 做一个区间,让用户来选择。

而 对于, choice 的这种字段。 应该把所有的选项,都罗列出来, 让用户自己选择。
gender 字段,应该做一个, 下拉框。 默认 全部选中。  如果用户选了 男 那么。 就过滤出 男性的人。 反之就是女
classes 字段, 也是一样的。

而对于, ForeignKey 或者 OneToOne   ManyToMany  这种的。 应该将被关联的这张表中, 所有的字段, 也做一个同样的展示。

开始搞:
  - 基类中配置, 一个 search_group = [] 
  - 和 一个函数  def get_search_group(self):    return self.search_group   预留钩子函数,让用户可以进行,权限的不同是否展示的功能

然后在 子类中。 开始进行。 具体的配置项:
  

class UserInfoHandler(StartHandler):
list_display = [StartHandler.display_checkbox, "name", "age", "depart", get_choice_txt("班级", "classes"),
get_choice_txt("性别", "gender"), StartHandler.display_edit, StartHandler.display_del]
per_page = 10
ordered_list = ["id"]
search_list = ["name__contains", "age__gt"]
action_list = [StartHandler.action_multi_delete, StartHandler.action_multi_init]
   has_add_btn = True # 配置组合搜索,想要展示哪些, 搜索的条件
search_group = ["gender", "classes", "depart"]

基类的处理:

search_group = []  # 方便,用户自己定制。组合搜索搜索的条件,和如果用户不配置,页面不显示组合搜索
def get_search_group(self):
return self.search_group per_page = 10 # 默认每页显示,多少数据。 也可在子类中,自行定制
def check_list_view(self, request, *args, **kwargs):
   ....... 其他代码在这里不贴了....... # ####################7. 处理组合搜索###################
from django.db.models import ForeignKey, ManyToManyField, OneToOneField
search_group = self.get_search_group() # ["gender", "classes", "depart"]
for item in search_group:
# 根据gender或者classes字符串,组自己对应的model类中,找到字段对象,再根据对象,获取关联的数据
field_obj = self.model_class._meta.get_field(item) # 固定用法mate 类,中的get_field() 就可以根据字符串获取对应的对象
# 对field_obj 的类型做判断。 来确定他是一个 choice 还是一个 foreignkey 外键
if isinstance(field_obj, ForeignKey) or isinstance(field_obj, ManyToManyField) or isinstance(field_obj,OneToOneField):
# 获取关联表中的, 数据 django1.0 版本使用 field_obj.rel.model.objects.all()
field_obj.related_model.objects.all() # django2.0版本使用这种方式 可以拿到, 被关联表的所有数据。
else:
# 获取 choice 的数据 field_obj.choices 使用这个对象下的 choices 方法,就能获取到,choices的元组.
print(field_obj.choices)
       # [(1, '男'), (2, '女')] [(1, '九年级一班'), (2, '九年级二班'), (3, '九年级三班')]
return render(request, "stark/changelist.html",
{"header_list": header_list, "data_list": data_list,
"body_list": body_list,
"pager": pager,
"add_btn": add_btn,
"search_list": search_list,
"search_value": search_value,
"action_dict": action_dict})
ok 做到这一部分,基本已经可以实现,组合搜索。 如何从数据库取出数据了! 但是如果可能更加的便捷,并且还可以支持动态的 搜索。 这样就不够了。
因为 子类中 search_group = ["gender", "classes", "depart"] 这里是写死了的, 而且没有任何的条件。 这里只是将所有的数据查询了出来。

并没有像, 比如我要查询 Depart 表中。 id 大于5 的这些数据。  如果要实现这种的,我们可能就需要一个字典。
例: {"field":"depart", "db_condition":{"id__gt":5}}  这种的数据结构。 通过 field字段,查询出对应的表。然后根据 条件dn_condition  来进行条件的,过滤。

这样的话,我在子类中的  search_group 列表, 可能就需要写很多的字典,进去。 而且还有一点,无法做到。根据前端发送过来的数据。进行 动态的筛选。  比如, 我不想要 大于5 了,  我想要 大于3 呢?

所以, 我这里使用了, 在 search_group 类表中,放置一个 对象进行去:

看一看 生成对象的类:

class Option(object):
'''使用组合搜索, 想要一些自己的搜索条件。 可扩展可继承'''
def __init__(self, field, db_condition=None):
'''
:param filed: 组合搜索关联的字段
:param db_condition: 数据库关联查询时查询的条件
'''
self.field = field
self.db_condition = db_condition
if not db_condition:
db_condition = {}
self.db_condition = db_condition def get_db_condition(self, request, *args, **kwargs):
'''预留继承后的重写函数, 重写后,次基类中的该方法,将被覆盖。 默认返回的是开发者输入的值。'''
'''重写后, 可根据,前端的返回值,进行一定的判断'''
return self.db_condition def get_queryset_or_tuple(self, model_class, request, *args, **kwargs):
'''根据字段去获取数据库关联的数据''' # 根据gender或者classes字符串,组自己对应的model类中,找到字段对象,再根据对象,获取关联的数据
field_obj = model_class._meta.get_field(self.field) # 固定用法mate 类,中的get_field() 就可以根据字符串获取对应的对象
# 对field_obj 的类型做判断。 来确定他是一个 choice 还是一个 foreignkey 外键
if isinstance(field_obj, ForeignKey) or isinstance(field_obj, ManyToManyField):
# 获取关联表中的, 数据 django1.0 版本使用 field_obj.rel.model.objects.all()
db_condition = self.get_db_condition(request, *args, **kwargs)
query_set = field_obj.related_model.objects.filter(**db_condition)
print(query_set)
else:
# 获取 choice 的数据 field_obj.choices
print(field_obj.choices)

ok  有个这个类的情况下:  我们在  handler 子类中。  search_group 列表:

    search_group = [
Option("gender"),
Option("classes"),
Option("depart"),
]

有了这个列表, 在视图函数中。 循环的时候, 拿到的就是。 这个对象。
直接调用,对象下的   get_queryset_or_tuple()  就可以了!   并且 这个函数中。
还有一个 获取条件的函数  self.get_db_condition(request, *args, **kwargs): 默认返回的就是一个 空字典。 代表没有任何的条件。

如果我想要加上条件, 也是很简单:

    search_group = [
Option("gender"),
Option("classes"),
Option("depart",{"id__gt":5}),
]

ok 没有问题。 最想要的动态查询呢?  也是很 easy   我只需要 再写一个 子类 并且继承  Option 类,然后重写 get_db_condition 就可以了

class MyOption(Option):
'''一个例子,这样重写之后。 Handler类中。 将使用这个方法,来生成对象。 从而覆盖掉基类的方法'''
'''并且可以根据,request。 传进来的数据,进行动态的查询。'''
def get_db_condition(self, request, *args, **kwargs):
return {"id__gt": request.GET.get("nid")}

相应的, serach_group  就需要, 使用这个子类。来构造对象: 并且也不需要在传入,条件参数

    search_group = [
Option("gender"),
Option("classes"),
MyOption("depart"),
]

这样,当对象去调用  get_db_condition  的时候。 会优先使用,自己类中的这个方法。

返回的就是  自己类中的这个方法,返回的 字典。  而且这个字典,是我们通过获取前端发送来的数据,从而进行生成  条件字典。
进而,获取相应的数据。
也就达到了,动态。 获取数据的目的。

stark组件开发之组合搜索实现思路的更多相关文章

  1. stark组件开发之组合搜索页面效果和 URL

    页面效果,只是样式.这个好解决!yield 的时候. 返回几个样式出去就好了! 并且前端写上一些样式的css {% if search_group_row_list %} <div class= ...

  2. stark组件开发之组合搜索高级显示和扩展

    上一篇,我只是做了. 默认的显示. def __iter__(self): '''默认显示. 用户可以自定制''' if isinstance(self.queryset_or_tuple, list ...

  3. stark组件开发之组合搜索基本显示

    数据的获取,上一篇,已经有了!然后就是,如何进行展示的问题.到了展示这里,又有了新的问题, 因为从数据库,取得的数据. 分为 queryset 和 tuple 两种数据结构.tuple 中,只是字符串 ...

  4. stark组件开发之关键搜索

    - 模糊搜索: 在页面生成一个表单.  以get 方式, 将数据提交到.当前查看页面. 后台接收数据,然后进行筛选过滤. 着个也需要,用户自定制!   定义一个  search_list  这个值,默 ...

  5. stark组件开发之列表页面定制列

    先看一张页面展示的效果图: 看一看我的  model 表!是什么样子: 看一看数据库是什么样子: 看 页面展示图,有表头. 有数据.模型表中,每一个字段, 都指定了 verbose_name. 如何解 ...

  6. stark组件开发之列表页面应用示例

    已经解决的,自定义的扩展函数,功能.但是 不可能返回. 一个 固定的页面把!  应该是,点击那条 记录之后的编辑, 就会跳转到相应的,编辑页面.所以 这个标签的  <a href="/ ...

  7. 轮播组件/瀑布流/组合搜索/KindEditor插件

    一.企业官网 ### 瀑布流 ​ Models.Student.objects.all() #获取所有学员信息 ​ 通过div进行循环图片和字幕 ​ 1.以template模板方法实现瀑布流以列为单位 ...

  8. stark组件开发之添加功能实现

    添加功能,还是使用, form 组件来完成!  并且 完成添加之后,需要保留原搜索条件. def memory_url(self): '''用于反向生成url, 并且携带,get请求的参数,跳转到下一 ...

  9. stark组件开发之编辑功能实现

    编辑功能.和添加一样! 唯一不同的就是, 需要编辑一个指定的  记录.这就需要,在列表页面, 渲染编辑的时候,添加一个 id 值: class UserInfoHandler(StartHandler ...

随机推荐

  1. MyPubMedID

    MyPubMedID是北京同舟云信息技术公司全新开发的新一代生物医学文献检索与分析平台. 该平台对PubMed全部内容进行重新清洗.组织.挖掘和开发,在完全消除PubMed检索歧义的同时,能够保证检索 ...

  2. vs 为什么使用#include "stdafx.h"

    原因:1.减少编译次数 2.减少不必要的处理 流程图: 这个跟宏定义#ifndef xx #define xx  coding here #endif //xx 区别在于: 宏定义是防止头文件重复包含 ...

  3. 前端 js加密 后台java 解密 RSA

    前端代码 : $.ajax({ type:"GET", url:"http://localhost:8084/getPulbicKey", dataType:& ...

  4. 导入myeclipse的java源码查看不了的问题

    导入之前自己的jar包后 ,可以正常使用了,但是发现按ctrl+鼠标左键查看不了源代码.attach source 来源后,还是没有效果. 先添加所要使用的jar包, 然后再添加源文件.最后终于显示成 ...

  5. Idea spring 配置文件报红 URI is not registered

    把报错的加到如下忽略列表中

  6. Log4j日志框架学习零到壹(一)

    日志是系统开发过程中用于排查问题重要的记录.通常使用日志来记录系统运行的行为,什么时间点发生了什么 事情.Java中常用的莫过于Log4j框架了.下面主要围绕Log4j的基础知识.Log4j的使用方式 ...

  7. Django之视图

    Django之视图   Django的View(视图) 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个 ...

  8. AE10.0及AE10.0以上的版本调用ESRI.ArcGIS.esriSystem出现的问题

    如果本地安装的是AE10.0以上,那么添加ESRI.ArcGIS.esriSystem引用时,会出现esriLicenseProductCode并不包含esriLicenseProductCodeAr ...

  9. Java数据类型(primitive)原始数据类型

    1.小心别溢出来. 要确保变量能存下来所保存的值. 你无法用小杯子装大值.好吧,其实可以,但是会损失某些信息,也就是所说的溢位.当判断到所使用的容器不足以装载时,编译器会试着防止珍重情况发生.举例来说 ...

  10. Spring Security 理解小记

    JWT 框架图如下, 来自博客https://blog.csdn.net/shehun1/article/details/45394405 个人觉得还不错.. 在开发中Spring boot 启用 加 ...