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

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

        {% if search_group_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_row_list %}
                            <div class="row">
                                {% for obj in row %}
                                    {{ obj|safe }}
                                {% endfor %}
                            </div>
                        {% endfor %}
                    </div>
                </div>
            </div>
        {% endif %}

模板代码

    def __iter__(self):
        ‘‘‘默认显示。 用户可以自定制‘‘‘
        yield "<div class=‘whole‘>"
        yield self.title
        yield "</div>"

        yield "<div class=‘others‘>"
        yield "<a>全部</a>"
        for item in self.queryset_or_list:
            text = self.option.get_text_func(item)
            yield "<a href=‘#‘>%s</a>" % text
        yield "</div>"

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

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

http://127.0.0.1:8000/stark/app01/userinfo/list/
http://127.0.0.1:8000/stark/app01/userinfo/list/?gender=1
http://127.0.0.1:8000/stark/app01/userinfo/list/?gender=1&classes=1
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):

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

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

class Option(object):
    ‘‘‘使用组合搜索, 想要一些自己的搜索条件。 可扩展可继承‘‘‘
    def __init__(self, field, db_condition=None, text_func=None, value_func=None):
        ‘‘‘
        :param filed:  组合搜索关联的字段
        :param db_condition:  数据库关联查询时查询的条件
        :param text_func: 此函数用于,页面组合搜索的文本和样式
        ‘‘‘
        self.field = field
        self.db_condition = db_condition
        self.text_func = text_func
        if not db_condition:
            db_condition = {}
        self.db_condition = db_condition

        self.is_choice = False  # 用于判断field对象里面是一个 choice列表 or 外键的queryset

    def get_value_func(self, field_obj):
        ‘‘‘
        获取对象 id 的函数。(从)
        :param field_obj:  (1, "男")  or model对象
        :return:
        ‘‘‘
        if self.text_func:
            return self.text_func(field_obj)

        if self.is_choice:
            return field_obj[0]
        return field_obj.pk

    def get_text_func(self, field_obj,):
        ‘‘‘
        获取文本,的函数。(从)
        :param field_obj:  (1, "男")  or model对象
        :return:
        ‘‘‘
        if self.text_func:
            return self.text_func(field_obj)

        if self.is_choice:
            return field_obj[1]
        return str(field_obj)

    def get_db_condition(self, request, *args, **kwargs):
        ‘‘‘预留继承后的重写函数, 重写后,次基类中的该方法,将被覆盖。 默认返回的是开发者输入的值。‘‘‘
        ‘‘‘重写后, 可根据,前端的返回值,进行一定的判断‘‘‘
        return self.db_condition

    def get_queryset_or_list(self, model_class, request, *args, **kwargs):
        ‘‘‘根据字段去获取数据库关联的数据‘‘‘

        # 根据gender或者classes字符串,组自己对应的model类中,找到字段对象,再根据对象,获取关联的数据
        field_obj = model_class._meta.get_field(self.field)  # 固定用法mate 类,中的get_field() 就可以根据字符串获取对应的对象
        title = field_obj.verbose_name
        # 对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)
            return SearchGroupRow(field_obj.related_model.objects.filter(**db_condition), self, title, request.GET)
            # 这里得到的是 Queryset 类型
        else:
            # 获取 choice 的数据 field_obj.choices
            self.is_choice = True
            return SearchGroupRow(field_obj.choices, self, title, request.GET)  # 这里得到的是  tuple 类型

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

class SearchGroupRow(object):
    def __init__(self, queryset_or_list, option, title, query_dict):
        self.query_dict = query_dict  # request.GET
        self.title = title
        self.option = option
        self.queryset_or_list = queryset_or_list

    def __iter__(self):
        ‘‘‘默认显示。 用户可以自定制‘‘‘
        # if isinstance(self.queryset_or_tuple, list):
        #     for item in self.queryset_or_tuple:
        #         yield "<a href=‘#‘>%s</a>" % item[1]
        # else:
        #     for item in self.queryset_or_tuple:
        #         if isinstance(item, Model):
        #             print(item)
        #         yield "<a href=‘#‘>%s</a>" % item
        yield "<div class=‘whole‘>"
        yield self.title
        yield "</div>"

        yield "<div class=‘others‘>"
        yield "<a>全部</a>"
        for item in self.queryset_or_list:
            text = self.option.get_text_func(item)

            # 需要request.GET
            query_dict = self.query_dict.copy()  # 做一次copy 不对原数据。在修改时造成影响
            query_dict._mutable = True  # QueryDict 默认不允许被修改。 添加这句就可以被修改了
            # 需要文本 背后的 id
            value = self.option.get_value_func(item)
            query_dict[self.option.field] = value
            yield "<a href=‘?%s‘>%s</a>" % (query_dict.urlencode(), text)
        yield "</div>"

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

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

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

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

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

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

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

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

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

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

    def __iter__(self):
        ‘‘‘默认显示。 用户可以自定制‘‘‘
        # if isinstance(self.queryset_or_tuple, list):
        #     for item in self.queryset_or_tuple:
        #         yield "<a href=‘#‘>%s</a>" % item[1]
        # else:
        #     for item in self.queryset_or_tuple:
        #         if isinstance(item, Model):
        #             print(item)
        #         yield "<a href=‘#‘>%s</a>" % item
        yield "<div class=‘whole‘>"
        yield self.title
        yield "</div>"

        yield "<div class=‘others‘>"
        yield "<a>全部</a>"
        for item in self.queryset_or_list:
            text = self.option.get_text_func(item)

            # 需要request.GET
            query_dict = self.query_dict.copy()  # 做一次copy 不对原数据。在修改时造成影响
            query_dict._mutable = True  # QueryDict 默认不允许被修改。 添加这句就可以被修改了
            # 需要文本 背后的 id
            value = self.option.get_value_func(item)
            origin_value_list = query_dict.getlist(self.option.field)  # 获取当前访问数据的
            query_dict[self.option.field] = value  # 更新当前访问数据的        # 这两部操作, 不要顺序倒了。 否则就没效果了!            if str(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)
        yield "</div>"

原文地址:https://www.cnblogs.com/chengege/p/10745830.html

时间: 2024-10-08 06:26:59

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

stark组件开发之添加按钮显示和URL

添加: 需求: 根据用户的权限, 决定是否,有添加按钮.  通过配置进行定制,预留钩子进行权限的判断. class StartHandler(object): has_add_btn = True # 指定配置,默认显示. 用户在子类中,自定制是否显示 def get_add_btn(self): '''预留钩子,子类中重写该方法. 根据权限的判断是否显示添加按钮''' if self.has_add_btn: return "<a class='btn btn-primary'>添

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

编辑功能.和添加一样! 唯一不同的就是, 需要编辑一个指定的  记录.这就需要,在列表页面, 渲染编辑的时候,添加一个 id 值: def memory_url(self, get_url_name, *args, **kwargs): '''用于反向生成url, 并且携带,get请求的参数,跳转到下一个网页''' name = "%s:%s" % (self.site.namespace, get_url_name) base_url = reverse(name, args=arg

stark组件之添加、修改页面内容搭建(七)

如何快速的进行数据的添加以及修改呢?modelform来实现是可以达到效果的,在这里就是应用了modelform,每一个表都不同,所以需要创建不同的modelform. def get_model_form_class(self, is_add,request,pk, *args,**kwargs): """ 获取添加.修改功能的modelform :return: """ if self.model_form_class: return sel

jQuery组件开发之表格隔行选中效果实现

一.效果展示如下 jQuery组件之表格插件源码 1 //表格选中插件 2 //方式一 3 (function($){ 4 var chosTabBgColor = function(options){ 5 //设置默认值 6 var options = $.extend({ 7 odd:"odd", //奇数 8 even:"even",//偶数 9 selected:"selected" 10 },options); 11 12 $(&quo

stark组件开发之提取公共视图函数

 路由问题, 已经解决! 然后就是视图函数的问题了: 不想重复写的解决途径就是, python  类的继承了! 写一个基类, 基类定义 增删改查. 然后其他的,全部去继承他! from django.urls import path, re_path from django.http import HttpResponse, JsonResponse from django.shortcuts import render, redirect, reverse from app01 import

Salesforce Lightning开发学习(二)Component组件开发实践

lightning的组件区分标准组件.自定义组件和AppExchange组件.标准组件由SF提供,自定义组件由developer自行开发,AppExchange组件由合作伙伴建立.下面我们写一个简单的列表demo来学习下自定义开发组件Component. 第一步:新建一个对象:电影,API:Movie__c,下表是其相关的字段   字段名 字段API 字段类型 描述 电影名称 Name 文本   主演 ToStar__c 文本(255)   主题曲 Theme__c 文本(255)   导演 D

stark组件配置,二层URL

1.django的admin配置 2 stark组件开发 3.2层url分发 4.小结 1.django的admin配置 model.py from django.db import models # Create your models here. class UserInfo(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.

Django——stark组件

stark组件是仿照django的admin模块开发的一套组件,它的作用是在网页上对注册的数据表进行增删改查操作. 一.配置 1.创建stark应用,在settings.py中注册stark应用 stark APP专门用于存放自定义组件的核心代码. manage.py@stark_demo > startapp stark 在settings.py文件注册stark: INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth'

iOS开发之剖析&quot;秘密&quot;App内容页面效果(二)

@前些天写了一篇"秘密"的Cell效果文章,但是与在工作中想要的效果还是有差距,而且扩展性很不好,于是重写封装,把整体视图都放到scrollView中,基本是和secret app 一模一样的效果了. @代码如下:(模糊效果的类就不写了,大家可以搜"UIImage+ImageEffects",还要导入Accelerate.framework) 1.MTSecretAppEffect.h #import <Foundation/Foundation.h>