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


    上一篇,我只是做了。 默认的显示。

        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  只是需要一个, 文本的信息。  而且是在这里做了判断,类型。
    改进一下, 既然我只需要一个文本信息。 那么 这个工作, 应该交给 使用者,自己进行指定。
    比如  默认返回   <a href='#'>男</a>   我想加点东西,比如  <a href='#'>男666</a>

    而且,并不是所有的都加。  如果我直接在  __iter__ 中。 给他加666。 也是可以的, 只需要在 search_group 列表。 加入对象的时候。为对象, 添加一个参数就可以了。

    但是我想换一种方式, 这个参数还是需要制定的, 但是获取文本的这个工作。 我交给   Option 类来做。 在类中添加一个参数。用于在最初的类型判断时, 就指定出,当前的 这个 field 对象。  是一个 choice 还是一个  Model 对象。

    class Option(object):
        '''使用组合搜索, 想要一些自己的搜索条件。 可扩展可继承'''
        def __init__(self, field, db_condition=None, text_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_text_func(self, field_obj):
            '''
            获取文本,的函数。(从)
            :param field_obj:  (1, "男")  or model对象
            :return:
            '''
            if self.text_func:  # 这个参数就是让用户来自己制定的。 下面展示如何使用。
                return self.text_func(field_obj)
        # 通过 is_choice 判断是否是 choice。 决定返回的是,元组中的 第二个元素。 还是关联表的表名(verbose_name="部门")
    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_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) return SearchGroupRow(field_obj.related_model.objects.filter(**db_condition), self) # 这里得到的是 Queryset 类型 else: # 获取 choice 的数据 field_obj.choices self.is_choice = True return SearchGroupRow(field_obj.choices, self) # 这里得到的是 tuple 类型

    在  UserInfoHandler 这个类中, 为search_group 添加 对象的时候。 可以选择性的为, Option类,添加一个函数进去。  如果添加了那么就会执行,传入的这个函数。 页面进行显示的时候, 就能够根据,用户自己的函数,逻辑进行展示。

    class UserInfoHandler(StartHandler):
        ...................
    # 配置组合搜索,想要展示哪些, 搜索的条件 search_group =   [ Option("gender",text_func=lambda field_obj:field_obj[1]+"666"), Option("classes"), MyOption("depart",text_func=lambda x:x.title + "123"), ]

    最后就是,原来的  __iter__ 改成啥样了呢?

    class SearchGroupRow(object):
        def __init__(self, queryset_or_tuple, option):
            self.option = option
            self.queryset_or_tuple = queryset_or_tuple
    
        def __iter__(self):
            '''默认显示。 用户可以自定制'''
            for item in self.queryset_or_tuple:
                text = self.option.get_text_func(item)
                yield "<a href='#'>%s</a>" % text

    变简单了!不再进行判断类型。 因为这个工作,前面已经做了。  这里就只是执行了一下 传进来 option 对象下的  get_text_func()这个函数。 并且将当前循环的  field 对象。 传给了他。
    最后看一下页面效果:

     能看出,  gender  我进行了自定制。 后面加了 666
    derpart  进行了自定制。 后面加了 123
    classes  没有自定制, 默认显示的就是。 模型表中  __str__ 返回的值。

     最后一点,就是标题了。 在每个前面,添加上一个标题。 这样就知道,我选择的是什么选项了:

     改动也不是很大。 就是通过  verbose_name  获取。 field 对象。 中的  verbose_name 设置的文字。

     然后 传给SearchGruop 类。 实例化的时候, 对象就拥有这个参数。
    然后  __iter__ 函数中,返回一个这个值就可以了。

    class SearchGroupRow(object):
        def __init__(self, queryset_or_list, option, title):
            self.title = title
            self.option = option
            self.queryset_or_list = queryset_or_list
    
        def __iter__(self):
            for item in self.queryset_or_list:
                yield self.title
                yield "<a>全部</a>"
                text = self.option.get_text_func(item)
                yield "<a href='#'>%s</a>" % text
    class Option(object):
        '''使用组合搜索, 想要一些自己的搜索条件。 可扩展可继承'''
        def __init__(self, field, db_condition=None, text_func=None):
            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_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 # 获取到,文件的 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) # 传进来 # 这里得到的是 Queryset 类型 else: # 获取 choice 的数据 field_obj.choices self.is_choice = True return SearchGroupRow(field_obj.choices, self, title) # 这里得到的是 tuple 类型
  • 相关阅读:
    【leetcode】第一个只出现一次的字符
    【leetcode】0~n1中缺失的数字
    054696
    053695
    053694
    053693
    053692
    053691
    053690
    053689
  • 原文地址:https://www.cnblogs.com/chengege/p/10745026.html
Copyright © 2020-2023  润新知