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()关闭窗口

Django之stark组件2的更多相关文章

  1. 【django之stark组件】

    一.需求 仿照django的admin,开发自己的stark组件.实现类似数据库客户端的功能,对数据进行增删改查. 二.实现 1.在settings配置中分别注册这三个app # Applicatio ...

  2. django 之 stark组件

    ----------------------------------------------------------------烦恼没完没了,内心动荡不安,呜呼哀哉. 一.有个特殊的需求,需要用sta ...

  3. Django之stark组件

    现在让我说啥是stark组件,我也说不清楚.反正从今天讲的知识来看,今天完成的就是自己写一个模块,这个模块包含了admin后台管理工具的一些比较好用的功能,我们把它提炼出来,也就是相当于自己写一个ad ...

  4. Django之stark组件的使用和总结

    Stark组件的使用 组件的字段 list_display=[] 需要显示的字段 list_display_links=[] #需要链接编辑字段 Stark_Model_Form=[] #设置Mode ...

  5. Django之stark组件1

    stark组件 stark组件是根据Django admin为原型写的一个组件,能够让我们告别增删改查.stark组件是可插拔试的组件, 移植性强,而且只用配置文件就能够得到想要的数据 一.stark ...

  6. stark组件之pop操作【模仿Django的admin】

    一.先看下什么django的admin的pop到底是个什么东西 其实就是这么一个东西, a.在添加页面,在一对多和多对多的项后加了一个+号 b.点击这个加号,会弹出对应的添加 页面,在新的添加 c.添 ...

  7. stark组件之批量操作【模仿Django的admin】

    一.先看下django的admin是如何实现批量操作 首先在配置类中定义一个函数 然后我们为这个函数对象设置一个属性,这个属性主要用来显示在select标签中显示的文本内容 最后把函数对象放到一个ac ...

  8. stark组件之搜索【模仿Django的admin】

    一.先看下django的admin是如何做搜索功能的 配置一个search_fields的列表就可以实现搜索的功能 class testbook(admin.ModelAdmin): # 第一步,定义 ...

  9. stark组件之路由分发【模仿Django的admin】

    一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...

随机推荐

  1. Win7下nginx默认80端口被System占用,造成nginx启动报错的解决方案

    Win7下nginx默认80端口被System占用,造成nginx启动报错的解决方案   在win7 32位旗舰版下,启动1.0.8版本nginx,显示如下错误:  [plain] 2012/04/0 ...

  2. 10. 修改端口号【从零开始学Spring Boot】

    转载:http://blog.csdn.net/linxingliang/article/details/51637017 spring boot 默认端口是8080,如果想要进行更改的话,只需要修改 ...

  3. Sending SMS And Dialing Numbers without User Consent(Context is not needed)

    Sending SMS And Dialing Numbers without User Consent Sending SMS does not require context or user in ...

  4. selenium从入门到应用 - 4,页面对象设计模式的实现

    本系列所有代码 https://github.com/zhangting85/simpleWebtest 本文将介绍一个Java+TestNG+Maven+Selenium的web自动化测试脚本环境下 ...

  5. textarea字数限制方法一例

    <!-- 控制textarea最大输入字数 --><script type="text/javascript">function checkLen(obj) ...

  6. 去除List中重复的元素

    今天碰到一个问题,想了好久都没有明白,网上找了一个文章,先收藏起来,有空了一定要想明白 用Set ,倘若list里边的元素不是基本数据类型而是对象,那么请覆写Object的boolean equals ...

  7. JAVA静态导入(inport static)详解

    在Java 5中,import语句得到了增强,以便提供甚至更加强大的减少击键次数功能,虽然一些人争议说这是以可读性为代价的.这种新的特性成为静态导入. 当你想使用static成员时,可以使用静态导入( ...

  8. SVN版本控制图标未显示或显示异常

    TortoiseSVN下载的文件和文件夹如果缺失了那些花花绿绿的状态小图标,很容易逼死某些强迫症患者,更何况这些小图标用处多多 接下来我会逐步展示从常规到非常规的一系列解决方案(不包括重装重启这一类) ...

  9. 多数据源动态关联报表的制作(birt为例)

    使用Jasper或BIRT等报表工具时,常会碰到一些很规的统计,用报表工具本身或SQL都难以处理,比方与主表相关的子表分布在多个数据库中,报表要展现这些数据源动态关联的结果.集算器具有结构化强计算引擎 ...

  10. 在Linux平台使用VNC连接树莓派

    你的Linux发行版本号可能已经包括了Remote Desktop Viewer(远程桌面)程序.你能够通过这个程序使用VNC连接你的树莓派.通常能够在Applications/Internet菜单以 ...