zoukankan      html  css  js  c++  java
  • Django之stark组件2

    action批量处理功能

    用户可以自定义批量处理功能,但是默认的有批量删除功能.

    ***思路***

    1,定义一个列表用来装action的类名并extend用户自定义列表

    2.循环该列表获取到函数名(用于执行)和方法名用于展示

    3.post提交,(selected_id是几个checkbox)(actions是类名)判断actions提交的是什么方法,就执行该方法.

    ############
    class ModelStark(object):
            actions=[]
    
    
    def get_actions_dict(self):
            temp=[]
            for item in self.config.new_actions:
                item_name = item.__name__
                item_desc=getattr(item,'desc',item_name.replace('_','  '))
                action_dict={
                    "name":item_name,
                    "desc":item_desc,
                }
                temp.append(action_dict)
            return temp
    
        @property
        def new_actions(self):
            temp=[ModelStark.actions_delete]
            temp.extend(self.actions)
            return temp
    
    
    
     def show_list(self,request):
            '''展示页面'''
            # self--->stark_class_obj--->每一个单独的配置类.
            if request.method=='POST':
                actions = request.POST.get('actions')
                if actions:
                    selected_id=request.POST.getlist('selected_id')
                    queryset=self.model.objects.filter(id__in=selected_id)
                    actions_func=getattr(self,actions)
                    actions_func(request,queryset)
    
    
    ######前端########
    <select name="actions" style="padding: 8px 10px">
                    <option value="">----------</option>
                    {% for item in showlist.get_actions_dict %}
                    <option value="{{ item.name }}">{{ item.desc }}</option>
                    {% endfor %}
                </select><button type="submit" class="btn btn-success">Go</button>
    actions
    class BookStark(ModelStark):
        def patch_init(self,request,queryset):
            queryset.update(price=100)
    
        patch_init.desc='批量初始化'
        actions = [patch_init]
    
    site.register(models.Book,BookStark)
    用户自定义使用方法

    2.过滤

    这里只过滤:一对多,多对对,choices

    ***思路***

    [需要注意的是,每一个字段的拼接都是过滤的条件filter]

    1.过滤的a标签,每点一次都要重新生成一份新的url拼接到原来的url上.(保留原始字段,并且每点击一次都会增加字段名和对应的id值)

    2.all标签在拼接的时候,把该字段的键值删除,点击的时候就不会过滤该键值

    3.过滤的条件用Q()来构建

    def get_filter_tags(self):
    
            handlerfilter =HandlerFilter(self.config.list_filter,self.request,self.config.model)
            # def __init__(self, list_filter, request, model):
            filter_dict=handlerfilter.process()
            return filter_dict
    
    
    class HandlerFilter(object):#['author','pub']
        def __init__(self,list_filter,request,model):
            self.list_filter=list_filter
            self.request=request
            self.model =model
            self.filter_dict={}
    
        def process(self):
            for filter_field in self.list_filter:
                self.init_data(filter_field)
                self.handler_all(filter_field)
                self.distribute(filter_field)
            return self.filter_dict
    
        def init_data(self,filter_field):
            '''初始化数据'''
            self.temp = []
            self._url = copy.deepcopy(self.request.GET)
            self.current_id = self._url.get(filter_field, 0)
            self.filter_field_obj = self.model._meta.get_field(filter_field)
            self.dict_name=getattr(self.filter_field_obj,'verbose_name',filter_field)
    
        def handler_all(self,filter_field):
            '''处理 all字段和页码bug'''
            if self._url.get('p'):
                self._url.pop('p')
            if self._url.get(filter_field):
                del self._url[filter_field]
                all_link = "<a href='?%s'>All</a>" % (self._url.urlencode())
            else:
                all_link = "<a href='#' class='active'>All</a>"
            self.temp.append(all_link)
    
        def distribute(self,filter_field):
            '''分发方法'''
            if isinstance(self.filter_field_obj,ManyToManyField) 
                    or isinstance(self.filter_field_obj,ForeignKey):
                self.M2MorFk(filter_field)
    
            elif self.filter_field_obj.choices:
                self.choices(filter_field)
    
            else:
                self.commom_file(filter_field)
    
        def M2MorFk(self,filter_field):
            '''字段多对多,或者一对多的处理'''
            filter_obj_list=self.filter_field_obj.related_model.objects.all()
            for obj in filter_obj_list:
                self._url[filter_field]=obj.id
                if self.current_id==str(obj.id):
                    link = "<a class='active' href='?%s'>%s</a>" % (self._url.urlencode(), str(obj))
                else:
                    link = "<a href='?%s'>%s</a>" % (self._url.urlencode(), str(obj))
                self.temp.append(link)
    
            self.filter_dict[self.dict_name]=self.temp
    
        def choices(self,filter_field):
            '''字段为choice的处理'''
            for num,text in self.filter_field_obj.choices:
                self._url[filter_field]=num
                if self.current_id==str(num):
                    link="<a class='active' href='?%s'>%s</a>"%(self._url.urlencode(),text)
                else:
                    link="<a href='?%s'>%s</a>"%(self._url.urlencode(),text)
    
                self.temp.append(link)
            self.filter_dict[self.dict_name]=self.temp
    
        def commom_file(self,filter_field):
            '''处理普通字段'''
            pass
    filter标签的构建

    知识点补充/通过一对多和多对对字段,怎么获取到关联的model:

    pub = models.ForeignKey(to='Publish',on_delete=models.CASCADE,verbose_name='出版社')

    获取到了pub字段,怎么获取到Publish这个model

    获取到了多对多的字段或一对多
    self.filter_field_obj = self.model._meta.get_field(filter_field)
    
    通过字段获取到model类.....filter_obj_list--->[obj,obj]
     filter_obj_list=self.filter_field_obj.related_model.objects.all()
    获取model方法
        def get_filter_connection(self,request):
            '''获取过滤条件'''
            _url = copy.deepcopy(request.GET)
            filter_connection=Q()
            for filter_field,val in _url.items():
                if filter_field in self.list_filter:
                    filter_connection.children.append((filter_field,val))
            return filter_connection
    构建Q

    用法:

        list_filter = ['name']
    用法

    pop方法:

    ***思路***

    1.通过form构建添加不同model的url,且获取该select标签的id

    2.构建是否显示pop按钮

    3.利用window.close()和window.opener方法来实现pop添加后自动关闭窗口和默认选中

    知识点补充/form字段获取model:

    #bfield是form字段
    related_model=bfield.field.queryset.model #获取该form字段对应的model

        def get_form(self,form):
            from django.forms.models import ModelChoiceField
            for bfield in form:
                if isinstance(bfield.field,ModelChoiceField):
                    bfield.is_pop = True  #用于是否显示pop按钮
    
                    related_model=bfield.field.queryset.model #获取该form字段对应的model
    
                    related_model_name=related_model._meta.model_name #获取model的名字
    
                    related_app_name=related_model._meta.app_label #获取model项目的名字
    
                    _url=reverse('%s_%s_add'%(related_app_name,related_model_name)) #反向解析url
    
                    bfield.url = _url+"?pop_in=id_%s"%bfield.name
    
            return form
    
        def add_view(self,request):
            '''增加的视图函数'''
            # self--->stark_class_obj--->每一个单独的配置类.
            ModelDeMo=self.get_model_class()
            old_form =ModelDeMo()
            if request.method=='POST':
                old_form = ModelDeMo(request.POST)
                if old_form.is_valid():
                    obj=old_form.save()
                    current_select =request.GET.get('pop_in')
    
                    if current_select:
                        ret={'id':obj.id,'text':str(obj),'current_select':current_select}
                        return render(request,'oprate/pop.html',{'ret':ret})
                    else:
                        return redirect(self.get_list_url())
    
            form =self.get_form(old_form)
            return render(request,'oprate/add.html',{'form':form})
    后端代码
    ######form表单的+标签路径##########'
    
    {% for data in form  %}
            <div class="form-item" style="position: relative">
            <label>{{ data.label }}</label>
            {{ data }}<span class="errors-form">{{ data.errors.0 }}</span>
            {% if data.url %}
                <a onclick="pop_window('{{ data.url }}')" style="position: absolute;right: -20px;top: 20px"><span style="font-size: 32px">+</span></a>
            {% endif %}
            </div>
        {% endfor %}
    
    
    ########pop html##########
    <script>
        window.opener.pop_handle('{{ ret.id }}','{{ ret.text }}','{{ ret.current_select }}');
        window.close();
    </script>
    
    
    #########add html########
    {% block extra_script %}
        <script>
        function pop_window(url) {
            window.open(url,'','width=600,height=400,top=200,left=200')
        }
        function pop_handle(id,text,current_select) {
            var $option =$('<option>');
            $option.html(text);
            $option.val(id);
            $option.attr('selected','selected');
            $('#'+current_select).append($option)
        }
        </script>
    {% endblock %}
    前端代码

    知识点补充window.open/close:

    window.open(url,'','设置大小')  (第三个参数)

    window.opener.func() 调用父窗口的方法

    window.close()关闭窗口

  • 相关阅读:
    E. Arranging The Sheep
    B. Box Fitting
    E. Permutation by Sum
    D. Corrupted Array
    联通 F677V2 光猫改桥接
    IntelliJ IDEA 常用快捷键整理
    Git 常用命令速查表
    Git 入门操作指南
    Anaconda 常用命令总结
    VS code 快捷键整理
  • 原文地址:https://www.cnblogs.com/chenxuming/p/9314308.html
Copyright © 2011-2022 走看看