页面效果,只是样式。这个好解决!
yield 的时候。 返回几个样式出去就好了! 并且前端写上一些样式的css

  1. {% if search_group_row_list %}
  2. <div class="panel panel-default">
  3. <div class="panel-heading">
  4. <i class="fa fa-filter" aria-hidden="true"></i> 快速筛选
  5. </div>
  6. <div class="panel-body">
  7. <div class="search-group">
  8. {% for row in search_group_row_list %}
  9. <div class="row">
  10. {% for obj in row %}
  11. {{ obj|safe }}
  12. {% endfor %}
  13. </div>
  14. {% endfor %}
  15. </div>
  16. </div>
  17. </div>
  18. {% endif %}

模板代码

  1. def __iter__(self):
  2. '''默认显示。 用户可以自定制'''
  3. yield "<div class='whole'>"
  4. yield self.title
  5. yield "</div>"
  6.  
  7. yield "<div class='others'>"
  8. yield "<a>全部</a>"
  9. for item in self.queryset_or_list:
  10. text = self.option.get_text_func(item)
  11. yield "<a href='#'>%s</a>" % text
  12. yield "</div>"

这样就可以了!  css 代码! 看自己想要啥样的。
这里面最重要的,是  href 超链接属性。

这个属性有个要求是, 组合搜索时,不能因为 点击了一个标签,而把上一步点击过的标签给忘记掉。
用几个  url 来展示一下:

  1. http://127.0.0.1:8000/stark/app01/userinfo/list/
  2. http://127.0.0.1:8000/stark/app01/userinfo/list/?gender=1
  3. http://127.0.0.1:8000/stark/app01/userinfo/list/?gender=1&classes=1
  4. http://127.0.0.1:8000/stark/app01/userinfo/list/?gender=1&classes=1&depart=3

可以看得出的是,这个是 GET 请求。
每次请求的时候,这个url  都会携带上,上次的 查询条件。

如何实现:

首先既然是查询, 那么每次请求的时候, 都会进入视图函数中。 并且调用 里面的方法,进而进入 __iter__  来为这个 href 进行赋值

所以,要做的就是,当有请求来的时候。我就将  request.GET  中的请求信息,做一个修改。

这个键 就是每个 field 对象的自己
他的值部分, choice就是元组中索引为 0 的值。 如果是外键, 那就是 field.pk 就能得到了!
request.GET 返回的是, 一个 QueryDict 对象。  并且他是默认不允许被修改的。 所以需要对一个参数进行更改。

然后每次用户进行点击不同的按钮的时候, 或发送不同的get 请求过来, 但是 get 请求的  键 是固定的, 我这里就只写了三个。
gender  classes  depart

既然 request.GET 返回的是, 一个 QueryDict 对象。 那么我就可以对这个字典的值, 进行修改。 但是键 永远都是这三个:
看看实现的代码:

视图中  每次请求都调用  option.get_queryset_or_list(self.model_class, request, *args, **kwargs):

  1. # ####################7. 处理组合搜索###################
  2. search_group_row_list = [] # 修改之后这里
  3. search_group = self.get_search_group() # 这里接受的多个 Option 的实例化对象
  4. for option in search_group:
  5. queryset_or_list = option.get_queryset_or_list(self.model_class, request, *args, **kwargs)
  6. search_group_row_list.append(queryset_or_list)

Option 类中的 get_queryset_or_list。 此函数又调用了 SearchGroupRow() 类。 (注意看参数的传入)

  1. class Option(object):
  2. '''使用组合搜索, 想要一些自己的搜索条件。 可扩展可继承'''
  3. def __init__(self, field, db_condition=None, text_func=None, value_func=None):
  4. '''
  5. :param filed: 组合搜索关联的字段
  6. :param db_condition: 数据库关联查询时查询的条件
  7. :param text_func: 此函数用于,页面组合搜索的文本和样式
  8. '''
  9. self.field = field
  10. self.db_condition = db_condition
  11. self.text_func = text_func
  12. if not db_condition:
  13. db_condition = {}
  14. self.db_condition = db_condition
  15.  
  16. self.is_choice = False # 用于判断field对象里面是一个 choice列表 or 外键的queryset
  17.  
  18. def get_value_func(self, field_obj):
  19. '''
  20. 获取对象 id 的函数。(从)
  21. :param field_obj: (1, "男") or model对象
  22. :return:
  23. '''
  24. if self.text_func:
  25. return self.text_func(field_obj)
  26.  
  27. if self.is_choice:
  28. return field_obj[0]
  29. return field_obj.pk
  30.  
  31. def get_text_func(self, field_obj,):
  32. '''
  33. 获取文本,的函数。(从)
  34. :param field_obj: (1, "男") or model对象
  35. :return:
  36. '''
  37. if self.text_func:
  38. return self.text_func(field_obj)
  39.  
  40. if self.is_choice:
  41. return field_obj[1]
  42. return str(field_obj)
  43.  
  44. def get_db_condition(self, request, *args, **kwargs):
  45. '''预留继承后的重写函数, 重写后,次基类中的该方法,将被覆盖。 默认返回的是开发者输入的值。'''
  46. '''重写后, 可根据,前端的返回值,进行一定的判断'''
  47. return self.db_condition
  48.  
  49. def get_queryset_or_list(self, model_class, request, *args, **kwargs):
  50. '''根据字段去获取数据库关联的数据'''
  51.  
  52. # 根据gender或者classes字符串,组自己对应的model类中,找到字段对象,再根据对象,获取关联的数据
  53. field_obj = model_class._meta.get_field(self.field) # 固定用法mate 类,中的get_field() 就可以根据字符串获取对应的对象
  54. title = field_obj.verbose_name
  55. # 对field_obj 的类型做判断。 来确定他是一个 choice 还是一个 foreignkey 外键
  56. if isinstance(field_obj, ForeignKey) or isinstance(field_obj, ManyToManyField):
  57. # 获取关联表中的, 数据 django1.0 版本使用 field_obj.rel.model.objects.all()
  58. db_condition = self.get_db_condition(request, *args, **kwargs)
  59. return SearchGroupRow(field_obj.related_model.objects.filter(**db_condition), self, title, request.GET)
  60. # 这里得到的是 Queryset 类型
  61. else:
  62. # 获取 choice 的数据 field_obj.choices
  63. self.is_choice = True
  64. return SearchGroupRow(field_obj.choices, self, title, request.GET) # 这里得到的是 tuple 类型

最后的SearchGroupRow类, 进行标签的渲染

  1. class SearchGroupRow(object):
  2. def __init__(self, queryset_or_list, option, title, query_dict):
  3. self.query_dict = query_dict # request.GET
  4. self.title = title
  5. self.option = option
  6. self.queryset_or_list = queryset_or_list
  7.  
  8. def __iter__(self):
  9. '''默认显示。 用户可以自定制'''
  10. # if isinstance(self.queryset_or_tuple, list):
  11. # for item in self.queryset_or_tuple:
  12. # yield "<a href='#'>%s</a>" % item[1]
  13. # else:
  14. # for item in self.queryset_or_tuple:
  15. # if isinstance(item, Model):
  16. # print(item)
  17. # yield "<a href='#'>%s</a>" % item
  18. yield "<div class='whole'>"
  19. yield self.title
  20. yield "</div>"
  21.  
  22. yield "<div class='others'>"
  23. yield "<a>全部</a>"
  24. for item in self.queryset_or_list:
  25. text = self.option.get_text_func(item)
  26.  
  27. # 需要request.GET
  28. query_dict = self.query_dict.copy() # 做一次copy 不对原数据。在修改时造成影响
  29. query_dict._mutable = True # QueryDict 默认不允许被修改。 添加这句就可以被修改了
  30. # 需要文本 背后的 id
  31. value = self.option.get_value_func(item)
  32. query_dict[self.option.field] = value
  33. yield "<a href='?%s'>%s</a>" % (query_dict.urlencode(), text)
  34. yield "</div>"

贴几张图片,技能很清除的。描述 这里发生了什么:
首先是 三组数据: 分别是  性别   班级   部门

看一看,他们在页面上的渲染: (这是没有get 参数。发送到数据库的时候)

我先点击一下  男  这个按钮:  这里就能看出一些效果了。 a标签的  href 属性,变了。 全部添加上了, gender=1

这次 换成  点击 九年级一班:

这就不再继续, 贴图片了!

每次点击之后,就会将这个  ?  之后的数据。全部 发送到后台。  之后的操作就是 跟字典一样的更新赋值操作。

最后拼接的时候  就是用  query_dict.urlencode 从这个字典中,取出这一串 数据。 拼接到 a 标签里面。
得到的效果就是这样了。

这里我也是想了,很久。 这个使用的方式, 真实微妙。 好用的很。

最后一点就是, 关于选中的样式问题, 和 全部按钮的问题!
对于选中的, 我们应该加一个样式。 未选中的是另一个样式:

这里做一个判断就好了!
request.GET 中的数据,我们能得到,  就在 querydict。
而当前 field 对象的id  value = self.option.get_value_func(item)  这个方式也已经获取到了!
然后就是做判断:

  1. def __iter__(self):
  2. yield "<div class='whole'>"
  3. yield self.title
  4. yield "</div>"
  5.  
  6. yield "<div class='others'>"
  7. yield "<a>全部</a>"
  8. for item in self.queryset_or_list:
  9. text = self.option.get_text_func(item)
  10.  
  11. # 需要request.GET
  12. query_dict = self.query_dict.copy() # 做一次copy 不对原数据。在修改时造成影响
  13. query_dict._mutable = True # QueryDict 默认不允许被修改。 添加这句就可以被修改了
  14. # 需要文本 背后的 id
  15. value = self.option.get_value_func(item)
  16. origin_value_list = query_dict.getlist(self.option.field) # 获取当前访问数据的
  17. query_dict[self.option.field] = value # 更新当前访问数据的
            # 这两部操作, 不要顺序倒了。 否则就没效果了!
    if str(value) in origin_value_list:
             query_dict.pop(self.option.field) # 这个就是判断如果当前请求没有变化。就从请求中删除掉这个数据
  18. yield "<a class='active' href='?%s'>%s</a>" % (query_dict.urlencode(), text)
  19. else:
  20. yield "<a href='?%s'>%s</a>" % (query_dict.urlencode(), text)
  21. yield "</div>"

stark组件开发之组合搜索页面效果和 URL的更多相关文章

  1. stark组件开发之组合搜索实现思路

    - 关键字搜索. 可以做到的效果是, 输入20. 后太通过 Q()  函数. 来实现.  搜索是一个大的问题点. -  要想实现组合搜索, 首先要 明确的一点是. 在我当前的页面上, 正在进行展示的是 ...

  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组件开发之列表页面自定义函数扩展

    对于展示页面, 可能需要显示一些. 数据库中,没有的字段. 比如, 删除按钮, 编辑按钮.  这个数据库,是没有的. 所以,可能就需要, 添加一个这个东西.  比如我在渲染的时候, 给他添加两个函数进 ...

  9. stark组件开发之列表页面预留钩子方法。 可根据用户的不同,显示不同的列

    要实现,这个方法.子类中 list_diplay 这个列表, 就不能够写死.他应该是 可以根据.用户的不同,返回不同的值. 所以 就需要一个函数, 可以进行判断当前用户是谁. 并且往这个列表中添加,他 ...

随机推荐

  1. Microsoft Speaker Recognition API

    azure说话人识别API 官方文档:https://westus.dev.cognitive.microsoft.com/docs/services/563309b6778daf02acc0a508 ...

  2. Python数据类型的内置函数之tuple(元组),dict(字典),set(集合)

    Python数据类型内置函数 - str(字符串) - list(列表) - tuple(元组) - dict(字典) - set(收集) tuple(元组)的操作 - (count)统计元组中元素出 ...

  3. Eclipse 上传 删除 下载 分析 hdfs 上的文件

    本篇讲解如何通过Eclipse 编写代码去操作分析hdfs 上的文件. 1.在eclipse 下新建Map/Reduce Project项目.如图:  项目建好后,会默认加载一系列相应的jar包. 下 ...

  4. 图表相同数据会自动合并问题(finereport)

    finereport中,对于图表的操作,当遇到需要显示多个重复分类下的多个值时,由于自动合并相同数据,无法达到效果反复查询手册无果后,困扰好久,终想到了一个解决的办法:1.给查询的数据添加个列序号,每 ...

  5. spring boot 拦截异常 统一处理

    spring boot 默认情况下会映射到 /error 进行异常处理,提示不友好,需要自定义异常处理,提供友好展示 1.自定义异常类(spring 对于 RuntimeException 异常才会进 ...

  6. MySQL(基础技能)

    一.概述 1.什么是数据库 ? 答:数据的仓库,如:在ATM的示例中我们创建了一个 db 目录,称其为数据库 2.什么是 MySQL.Oracle.SQLite.Access.MS SQL Serve ...

  7. 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值

    可以在处理Post方法的Action添加一个特性:[ValidateInput(false)],这样处理就更加有针对性,提高页面的安全性. [HttpPost][ValidateInput(false ...

  8. sys模块学习记录

    import sys s = sys.argv #命令行参数List,第一个元素是程序本身路径 #sys.exit() #退出程序,正常退出时exit(0) s = sys.version #获取Py ...

  9. [SQL]批量修改存储过程视图

    存储过程与视图适用 ); )='w_sp_Sms_ExpeOrKeepEmpl'; DECLARE C_TABLES CURSOR FAST_FORWARD FOR SELECT NAME FROM ...

  10. python之路:模块初识

    python王者开发之路:模块初识 模块初识我现在讲的确有点早.不过没关系,后面我会详细说模块. 模块,也就是库,是python三剑客之一.这三剑客,函数.库和类,都是由程序编写而成的.之所以我先说模 ...