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()关闭窗口
Django之stark组件2的更多相关文章
- 【django之stark组件】
一.需求 仿照django的admin,开发自己的stark组件.实现类似数据库客户端的功能,对数据进行增删改查. 二.实现 1.在settings配置中分别注册这三个app # Applicatio ...
- django 之 stark组件
----------------------------------------------------------------烦恼没完没了,内心动荡不安,呜呼哀哉. 一.有个特殊的需求,需要用sta ...
- Django之stark组件
现在让我说啥是stark组件,我也说不清楚.反正从今天讲的知识来看,今天完成的就是自己写一个模块,这个模块包含了admin后台管理工具的一些比较好用的功能,我们把它提炼出来,也就是相当于自己写一个ad ...
- Django之stark组件的使用和总结
Stark组件的使用 组件的字段 list_display=[] 需要显示的字段 list_display_links=[] #需要链接编辑字段 Stark_Model_Form=[] #设置Mode ...
- Django之stark组件1
stark组件 stark组件是根据Django admin为原型写的一个组件,能够让我们告别增删改查.stark组件是可插拔试的组件, 移植性强,而且只用配置文件就能够得到想要的数据 一.stark ...
- stark组件之pop操作【模仿Django的admin】
一.先看下什么django的admin的pop到底是个什么东西 其实就是这么一个东西, a.在添加页面,在一对多和多对多的项后加了一个+号 b.点击这个加号,会弹出对应的添加 页面,在新的添加 c.添 ...
- stark组件之批量操作【模仿Django的admin】
一.先看下django的admin是如何实现批量操作 首先在配置类中定义一个函数 然后我们为这个函数对象设置一个属性,这个属性主要用来显示在select标签中显示的文本内容 最后把函数对象放到一个ac ...
- stark组件之搜索【模仿Django的admin】
一.先看下django的admin是如何做搜索功能的 配置一个search_fields的列表就可以实现搜索的功能 class testbook(admin.ModelAdmin): # 第一步,定义 ...
- stark组件之路由分发【模仿Django的admin】
一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...
随机推荐
- ECSHOP后台开发模块步骤
一.建数据库二.添加到后台导航栏并配置相关语言包三.权限配置四.添加增删查改五.增加其他功能(复制,搜索(暂时调不出来页面),排序,转移,AJAX) 以添加支付信息模块为例 第一步首先我们用phpmy ...
- jsp中URL传递中文參数的处理
在页面的url中使用encodeURI(encodeURI(中文)).对中文进行编码.并在server的java程序中使用URLDecoder.decode(中文, "UTF-8" ...
- scss使用后的简单入门总结
端午节第一天 将之前做的一个小demo的css样式改为了scss 好吧 改完了 赶紧由小兵 升级到中尉了 什么是scss? 我的理解是scss 就是css 的预处理器,使css变得更加富有逻辑. 有什 ...
- 斯坦福《机器学习》Lesson4感想--1、Logistic回归中的牛顿方法
在上一篇中提到的Logistic回归是利用最大似然概率的思想和梯度上升算法确定θ,从而确定f(θ).本篇将介绍还有一种求解最大似然概率ℓ(θ)的方法,即牛顿迭代法. 在牛顿迭代法中.如果一个函数是,求 ...
- python ——单下划线(约定)
命名规则: 通常使用小写单词,必要时用下划线分隔增加可读性. 使用一个前导下划线仅用于不打算作为类的公共接口的内部方法和实例变量. Python不强制要求这样; 它取决于程序员是否遵守这个约定. 使用 ...
- jquery.validate.js 验证表单时,在IE当中未验证就直接提交的原因
jquery.validate.js 验证表单时,在IE当中未验证就直接提交的原因 今天利用了jquery.validate.js来验证表单,发现在火狐.谷歌浏览器当中都可以进行验证,但是在IE系列浏 ...
- ThinkPHP连接主从数据库
config.php文件设置如下: return array( 'URL_MODE'=>0, 'DB_TYPE'=>'mysql', 'DB_HOST'=>'localhos ...
- 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生
[转].NET(C#):浅谈程序集清单资源和RESX资源 目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...
- MQTT--Mosquitto的配置文件
Mosquitto的配置文件存放在/etc/mosquitto/mosquitto.conf 配置文件具体的配置内容为: # ===================================== ...
- Eclipse 经常使用快捷键
一.File 二.Edit Ctrl + 1 有益写错,让编辑器提醒改动 三.Refactor 抽取为全局变量 Refactor - Convert Local Variable to Field ...