• 优雅装饰器

import functools

def wrapper(func):
@functools.wraps(func)
# 保留原函数的信息
def inner(*args, **kwargs):
return func(*args, **kwargs)
return inner
@wrapper
def f1():
print('f1') @wrapper
def f2():
print('f1') print(f1.__name__)
print(f2.__name__)
"""
之前
inner
inner
""" """
之后
f1
f2
"""

装饰器保留原函数的信息


  • 判断是函数,还是变量
    判断arg是函数则打印1,arg是方法则打印2

from types import MethodType,FunctionType
def check(arg):
"""
判断arg是函数则打印1,arg是方法则打印2
:param arg:
:return:
"""
if isinstance(arg,MethodType):
print(2)
elif isinstance(arg,FunctionType):
print(1)
else:
print('不认识') def func():
pass class Foo(object):
def display(self):
pass check(func)
check(Foo.display)
check(Foo().display) """
1
1
2
"""

from types import MethodType,FunctionType


  • 类传变量的一种方式

实例方法传参,要传实例对象本身

class RoleConfig(object):

    def f1(self, arg):
print('f1', arg) def f2(self, arg):
print('f2', arg) list_display = [f1, f2] obj = RoleConfig()
for item in RoleConfig.list_display:
item(obj, 2)
# obj就是self,实例变量本身
# 传变量的一种方式

view

  • 利用列表储存函数对象
   一个进程两次调用类变量

class RoleConfig(object):

    def f1(self, arg):
print('f1', arg) def f2(self, arg):
print('f2', arg) def f3(self, arg):
print('f3', arg) list_display = [f1, f2] def get_list_display(self):
self.list_display.insert(0, RoleConfig.f3)
return self.list_display
obj1 = RoleConfig()
for item in obj1.get_list_display():
item(obj1, 2) # 刚开始这时候列表里还没有,加进f3, obj2 = RoleConfig()
for item in obj2.get_list_display():
print('obj2----')
item(obj2, 6) # 这时候列表里有了f3,再插入一个f3反回。所以此处列表里有四个 # 利用类的变量列表,储存对象
# 一个进程对类操作了两次
"""
f3 2
f1 2
f2 2
f3 6
f3 6
f1 6
f2 6
"""

view

class RoleConfig(object):

    def f1(self, arg):
print('f1', arg) def f2(self, arg):
print('f2', arg) def f3(self, arg):
print('f3', arg) list_display = [f1, f2] def get_list_display(self):
v = []
v.extend(self.list_display)
v.insert(0, RoleConfig.f3)
return v obj1 = RoleConfig()#[f1,f2]
for item in obj1.get_list_display():# [f3,f1,f2]
item(obj1, 2) print('---------------')
obj2 = RoleConfig()#[f1,f2]
for item in obj2.get_list_display(): #[f3,f1,f2]
item(obj2, 6)
print('+++++') """
f3 2
---------------
f3 6
f1 6
f2 6
+++++
f1 2
---------------
f3 6
f1 6
f2 6
+++++
f2 2
---------------
f3 6
f1 6
f2 6
+++++
"""

view

  • 利用yield取数据
不要一次性取出来,占内存

   以前的:
def func(request):
result = [] data_list = models.Users.objects.all()
for row in data_list:
temp = "%s%s" (row.name,row.pwd,)
result.append(temp) return render(request,'xxx.html',{'result':result}) xxx.html {% for row in result %}
{{row}}
{% endfor%} 现在的: def get_result(data_list):
for row in data_list:
temp = "%s%s" (row.name,row.pwd,)
yield temp def func(request): data_list = models.Users.objects.all()
result = get_result(data_list) return render(request,'xxx.html',{'result':result}) xxx.html
{# 生成器,不断去调用#}
{% for row in result %}
{{row}}
{% endfor%}

view


复选框实现

  • 复选框函数 mark_safe
def display_checkbox(self, row=None, header=False):
# 选择框功能 默认None,表头 如果是表头,则显示相应字段
if header:
return "选择" # 表头第一个字段,可以自定制
return mark_safe("<input type='checkbox' name='pk' value='%s' />" % row.pk)
# 安全渲染**** 选中行数据pk

view

  • 复选框函数实现与显示

调用复选框函数,拿到标签渲染

def changelist_view(self, request):
# 所有URL的查看列表页面
# 获取表所有数据
queryset = self.model_class.objects.all().order_by(*self.get_order_by()) # 要显示的字段
list_display = self.list_display header_list = [] # 表头列表
if list_display: # 判断有没有显示字段
for name_or_func in list_display:
if isinstance(name_or_func, FunctionType): # 判断是不是函数,是则执行
verbose_name = name_or_func(self, header=True)
else: # 不是函数,则按规则去取字段的名称
verbose_name = self.model_class._meta.get_field(name_or_func).verbose_name
header_list.append(verbose_name)
else: # 没有显示字段列表,取表名作为表头
header_list.append(self.model_class._meta.model_name) body_list = [] # 表体列表
for row in queryset: # 从查找到的queryset对象里取
row_list = [] # 行列表
if not list_display: # 没有规定显示的字段
row_list.append(row) # 直接将一条queryset 放到行列表里面
body_list.append(row_list) # 再放到表体
continue
for name_or_func in list_display: # 按照要显示的字段,取数据,遇到函数就执行显示复选框,并返回该行对象
if isinstance(name_or_func, FunctionType): # 判断是否是功能函数
val = name_or_func(self, row=row) # 执行函数反回功能内容
else: # 其他字段的数据正常取
val = getattr(row, name_or_func) # getattr 映射 每个要显示字段名 ,取queryset里面的字段值
row_list.append(val) # 添加到行
body_list.append(row_list) # 添加到表体
# 反回渲染页面
return render(request, 'stark/changelist.html', {'header_list': header_list, 'body_list': body_list})

view

  • 前端页面

循环取值

<div>
<table class="table table-bordered"> {# 基于bootstrap 创建table表 #}
<thead> {# 表头 #}
<tr>
{% for item in header_list %}
<th>{{ item }}</th>
{% endfor %}
</tr>
</thead>
<tbody> {# 表体 #}
{% for row_list in body_list %}
<tr>
{% for col in row_list %}
<td>{{ col }}</td>
{% endfor %} </tr>
{% endfor %}
</tbody>
</table> </div>

view

  • 自定义的配置类

from stark.service.stark import site, StarkConfig
from app01 import models site.register(models.UserInfo) class DepartConfig(StarkConfig):
# 自定义的配置类
list_display = [StarkConfig.display_checkbox,'id', 'name', 'user']
# 自定义的显示字段 site.register(models.Depart, DepartConfig)

view




编辑删除功能函数实现

利用函数封装名称标签,组装表每行时 Functiontype判断,取不同值放入row_list

def display_edit(self, row=None, header=False):
if header:
return "编辑" return mark_safe('<a href="%s"><i class="fa fa-edit" aria-hidden="true"></i></a></a>' % self.reverse_edit_url(row)) def display_del(self, row=None, header=False):
if header:
return "删除" return mark_safe('<a href="%s"><i class="fa fa-trash-o" aria-hidden="true"></i></a>' % self.reverse_del_url(row)) def display_edit_del(self, row=None, header=False):
if header:
return "操作"
tpl = """<a href="%s"><i class="fa fa-edit" aria-hidden="true"></i></a></a> |
<a href="%s"><i class="fa fa-trash-o" aria-hidden="true"></i></a>
""" %(self.reverse_edit_url(row),self.reverse_del_url(row),)
return mark_safe(tpl)

list display function



前端循环取组装好的列表里面的值即可

{% block content %}
<div>
{% if add_btn %}
<div style="margin: 5px 0;">
{{ add_btn }}
</div>
{% endif %}
<table class="table table-bordered">
<thead>
<tr>
{% for item in header_list %}
<th>{{ item }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row_list in body_list %}
<tr>
{% for col in row_list %}
<td>{{ col }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

view

添加数据功能实现

modeform 实现表单更改验证

model_form_class = None

def get_add_btn(self):
return mark_safe('<a href="%s" class="btn btn-success">添加</a>' % self.reverse_add_url()) def get_model_form_class(self):
"""
获取ModelForm类 # 用于编辑 和 添加数据的表单
:return: #根据是否有自定义配置,返回不同表单
"""
if self.model_form_class:
return self.model_form_class # 其他表的配置,如果有自定义的表单则返回自定义的 class AddModelForm(forms.ModelForm): # 添加功能的表单,所有数据都需要填写,所以默认所有字段都要
class Meta:
model = self.model_class
fields = "__all__" return AddModelForm

ModelForm

def changelist_view(self, request):
"""
所有URL的查看列表页面 # 将添加按钮功能,添加到这页面视图
:param request:
:return:
"""
queryset = self.model_class.objects.all().order_by(*self.get_order_by()) # ##### 添加按钮 ######
add_btn = self.get_add_btn()
...... def add_view(self, request):
"""
所有添加页面,都在此函数处理
使用ModelForm实现
:param request:
:return:
"""
AddModelForm = self.get_model_form_class()
if request.method == "GET":
form = AddModelForm()
return render(request, 'stark/change.html', {'form':form}) form = AddModelForm(request.POST) # 校验数据
if form.is_valid():
form.save() # 保存
return redirect(self.reverse_list_url()) # 添加完反回主页面
return render(request, 'stark/change.html', {'form': form})

add_view

class AdminSite(object):
def __init__(self):
self._registry = {}
self.app_name = 'stark'
self.namespace = 'stark' def register(self, model_class, stark_config=None):
"""
注册表类
:param model_class: 表类class
:param stark_config: 自定义配置
:return:
"""
if not stark_config:
stark_config = StarkConfig self._registry[model_class] = stark_config(model_class, self) # 实例对象传参
"""
{
models.UserInfo: StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
models.Role: RoleConfig(models.Role) # 封装:model_class=Role,site=site对象
}
""" def get_urls(self):
# 获取url
urlpatterns = [] #url 列表 # urlpatterns.append(url(r'^x3/', ([
# url(r'^add/', self.x1),
# url(r'^change/', self.x1),
# url(r'^del/', self.x1),
# url(r'^edit/', self.x1),
# ],None,None))) for k, v in self._registry.items():
# k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
# k=modes.Role,v=RoleConfig(models.Role) # 封装:model_class=Role,site=site对象
app_label = k._meta.app_label
model_name = k._meta.model_name
urlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))
# 表类所在app/表类名的组装 一个表类绑定的操作url
return urlpatterns @property
def urls(self):
return self.get_urls(), self.app_name, self.namespace
# url列表
# 返回的元组 site = AdminSite()

AdminSite

编辑视图函数

def change_view(self, request, pk):
"""
所有编辑页面
:param request:
:param pk: 操作该条数据的pk,路由有设置
:return:
"""
obj = self.model_class.objects.filter(pk=pk).first()
if not obj:
return HttpResponse('数据不存在') ModelFormClass = self.get_model_form_class()
if request.method == 'GET':
form = ModelFormClass(instance=obj) # instance=obj 默认原先的编辑数据
return render(request,'stark/change.html',{'form':form})
form = ModelFormClass(data=request.POST,instance=obj)
if form.is_valid():
form.save()
return redirect(self.reverse_list_url())
return render(request, 'stark/change.html', {'form': form})

编辑视图处理函数

{% block content %}
<div style="width: 680px;margin: 0 auto;">
<form class="change" method="post">
{% csrf_token %}
{% for filed in form %}
<div class="form-group">
<label>{{ filed.label }}</label>
{{ filed }}
{{ filed.errors.0 }}
</div>
{% endfor %} <button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
{% endblock %}

编辑前端页面

def delete_view(self, request, pk):
"""
所有删除页面
:param request:
:param pk:
:return:
"""
if request.method == "GET":
return render(request,'stark/delete.html',{'cancel_url':self.reverse_list_url()})
# 跳转到确认页面 # 取消反回的url
self.model_class.objects.filter(pk=pk).delete() # 不是GET请求,说明确认删除
return redirect(self.reverse_list_url())

删除视图处理函数

{% extends 'stark/layout.html' %}
{% block css %} {% endblock %}
{% block content %}
<div >
<form method="post">
{% csrf_token %}
<p>是否确定要删除?</p>
<a href="{{ cancel_url }}" class="btn btn-default">取消</a>
<button type="submit" class="btn btn-danger">确 认</button>
</form>
</div>
{% endblock %}

删除确认页面

def get_urls(self):
info = self.model_class._meta.app_label, self.model_class._meta.model_name urlpatterns = [
url(r'^list/$', self.wrapper(self.changelist_view), name='%s_%s_changelist' % info),
url(r'^add/$', self.wrapper(self.add_view), name='%s_%s_add' % info),
url(r'^(?P<pk>\d+)/change/', self.wrapper(self.change_view), name='%s_%s_change' % info),
url(r'^(?P<pk>\d+)/del/', self.wrapper(self.delete_view), name='%s_%s_del' % info),
] extra = self.extra_url()
if extra:
urlpatterns.extend(extra) return urlpatterns
def extra_url(self):
pass

每张表类绑定的路由

反向解析,前端提交变更的路由路径

def reverse_list_url(self):
app_label = self.model_class._meta.app_label
model_name = self.model_class._meta.model_name
namespace = self.site.namespace
name = '%s:%s_%s_changelist' % (namespace, app_label, model_name)
list_url = reverse(name)
return list_url def reverse_add_url(self):
app_label = self.model_class._meta.app_label
model_name = self.model_class._meta.model_name
namespace = self.site.namespace
name = '%s:%s_%s_add' % (namespace, app_label, model_name)
add_url = reverse(name)
return add_url def reverse_edit_url(self,row):
app_label = self.model_class._meta.app_label
model_name = self.model_class._meta.model_name
namespace = self.site.namespace
name = '%s:%s_%s_change' % (namespace, app_label, model_name)
edit_url = reverse(name, kwargs={'pk': row.pk})
return edit_url def reverse_del_url(self,row):
app_label = self.model_class._meta.app_label
model_name = self.model_class._meta.model_name
namespace = self.site.namespace
name = '%s:%s_%s_del' % (namespace, app_label, model_name)
del_url = reverse(name, kwargs={'pk': row.pk})
return del_url @property
def urls(self):
return self.get_urls()

路由解析


应用配置app01/stark.py

class DepartModelForm(forms.ModelForm):
class Meta:
model = models.Depart
fields = "__all__" def clean_name(self):
return self.cleaned_data['name'] class DepartConfig(StarkConfig): #继承默认配置类
list_display = [StarkConfig.display_checkbox, 'id', 'name', 'tel', 'user', StarkConfig.display_edit_del]
model_form_class = DepartModelForm def changelist_view(self, request):
return HttpResponse('自定义列表页面') site.register(models.Depart, DepartConfig)

view







注册类入口
class AdminSite(object):
def __init__(self):
self._registry = {}
self.app_name = 'stark'
self.namespace = 'stark' def register(self, model_class, stark_config=None):
"""
注册表类
:param model_class: 表类class
:param stark_config: 自定义配置
:return:
"""
if not stark_config:
stark_config = StarkConfig self._registry[model_class] = stark_config(model_class, self) # 实例对象传参
"""
{
models.UserInfo: StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
models.Role: RoleConfig(models.Role) # 封装:model_class=Role,site=site对象
}
""" def get_urls(self):
# 获取url
urlpatterns = [] #url 列表 # urlpatterns.append(url(r'^x3/', ([
# url(r'^add/', self.x1),
# url(r'^change/', self.x1),
# url(r'^del/', self.x1),
# url(r'^edit/', self.x1),
# ],None,None))) for k, v in self._registry.items():
# k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
# k=modes.Role,v=RoleConfig(models.Role) # 封装:model_class=Role,site=site对象
app_label = k._meta.app_label
model_name = k._meta.model_name
urlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))
# 表类所在app/表类名的组装 一个表类绑定的操作url
return urlpatterns @property
def urls(self):
return self.get_urls(), self.app_name, self.namespace
# url列表
# 返回的元组 site = AdminSite()

class AdminSite


自定义思路
a.有自定义配置类的,重写继承的默认类变量,然后再由类方法自己去调用
b. 在自定义配置类,直接重写继承配置类的默认方法

1. 排序规则

2. 显示列
第一种方法:
class UserInfoConfig(StarkConfig):
list_display = ['id','title',StarkConfig.display_edit,StarkConfig.display_del]
site.register(models.UserInfo,UserInfoConfig)
第二种方法:
class UserInfoConfig(StarkConfig):
order_by = ['-id'] def get_list_display(self):
return ['id','title',StarkConfig.display_edit,StarkConfig.display_del]

1. 排序规则


3. 添加按钮
class UserInfoConfig(StarkConfig):
list_display = ['id','title',StarkConfig.display_edit,StarkConfig.display_del]
def get_add_btn(self):
# 显示
# return mark_safe('<a href="%s" class="btn btn-success">添加</a>' % self.reverse_add_url()) # 不显示
return None site.register(models.UserInfo,UserInfoConfig)

3. 添加按钮

4. 定制ModelForm
第一种方法:
class DepartModelForm(forms.ModelForm):
class Meta:
model = models.Depart
fields = "__all__" def clean_name(self):
return self.cleaned_data['name'] class DepartConfig(StarkConfig):
list_display = [StarkConfig.display_checkbox,'id', 'name', 'tel', 'user',StarkConfig.display_edit_del]
model_form_class = DepartModelForm
第二种方法:
class DepartModelForm(forms.ModelForm):
class Meta:
model = models.Depart
fields = "__all__" def clean_name(self):
return self.cleaned_data['name'] class DepartConfig(StarkConfig):
list_display = [StarkConfig.display_checkbox,'id', 'name', 'tel', 'user',StarkConfig.display_edit_del] def get_model_form_class(self): return DepartModelForm

4. 定制ModelForm


5. 自定义列表页面
class DepartConfig(StarkConfig):
list_display = [StarkConfig.display_checkbox,'id', 'name', 'tel', 'user',StarkConfig.display_edit_del]
model_form_class = DepartModelForm def changelist_view(self, request):
return HttpResponse('自定义列表页面') site.register(models.Depart, DepartConfig) 6. 增加URL
class RoleConfig(StarkConfig): order_by = ['-id', ]
list_display = [StarkConfig.display_checkbox,'id','title',StarkConfig.display_edit,StarkConfig.display_del] def extra_url(self):
data = [
url(r'^xxxxxxx/$', self.xxxxxx),
] return data def xxxxxx(self,request):
print('....') return HttpResponse('xxxxx') site.register(models.Role,RoleConfig) 7. 自定制URL class RoleConfig(StarkConfig): order_by = ['-id', ]
list_display = [StarkConfig.display_checkbox,'id','title'] def get_add_btn(self):
return False def extra_url(self):
data = [
url(r'^xxxxxxx/$', self.xxxxxx),
] return data def xxxxxx(self,request):
print('....') return HttpResponse('xxxxx') def get_urls(self):
info = self.model_class._meta.app_label, self.model_class._meta.model_name urlpatterns = [
url(r'^list/$', self.wrapper(self.changelist_view), name='%s_%s_changelist' % info),
] extra = self.extra_url()
if extra:
urlpatterns.extend(extra) return urlpatterns site.register(models.Role,RoleConfig)

5. 自定义列表页面


stark 增删改的更多相关文章

  1. stark——增删改页面

    一.制作添加页面 1.前置准备 (1)修改增删改的视图函数名 class ModelStark(object): def add_view(self, request): return HttpRes ...

  2. stark组件的增删改(新)

      1.效果图 2.详细步骤解析 3.总结.代码   1.效果图 增 删除 改 2.详细步骤解析 1.构造增删改查url,反向解析 2.ModelForm定制add.edit页面 3.starak中的 ...

  3. stark组件的增删改

      1.效果图 2.详细步骤解析 3.总结.代码   1.效果图 增 删除 改 2.详细步骤解析 1.构造增删改查url,反向解析 2.ModelForm定制add.edit页面 3.starak中的 ...

  4. day67 crm(4) stark组件的增删改 以及 model_from使用和from组件回顾

        前情提要:Django  stark 组件开发的 增删改,  model_form组件的使用 form组件的回顾 一:list_display_link  创建 功能描述:   使包含的字段能 ...

  5. 9 stark组件 增删改

    1.效果图 2.详细步骤解析 1.构造增删改查url,反向解析 2.ModelForm定制add.edit页面 3.staradmin中的ModelForm 3.总结.代码 1.知识点 1.解决代码重 ...

  6. 模拟admin组件自己开发stark组件之增删改查

    增删改查,针对视图 我们需要modelform来创建,可自动生成标签,我们还要考虑用户是不是自己定制,依然解决方法是,继承和重写 app01下的joker.py文件 class BookModelFo ...

  7. popup的简单应用举例(具体在增删改查组件中用到)以及补充的知识点

    一.首先说一下自执行函数 1. 立即执行函数是什么?也就是匿名函数 立即执行函数就是 声明一个匿名函数 马上调用这个匿名函数 2.popup的举例 点击,弹出一个新的窗口.保存完事,页面不刷新数据就返 ...

  8. day84-仿照admin实现一个自定义的增删改查组件

    一.admin的使用 app01的admin.py文件: class BookConfig(admin.ModelAdmin): list_display=[] list_display_links= ...

  9. stark - 增、删、改

    一.效果图 二.增.删.改 知识点: 1.解决代码重用 {% include 'form.html' %} 2.自定制配置modelform 每张表,就可自定义配置 labels , widges.. ...

随机推荐

  1. Mysql 事件event_scheduler是OFF

    1 在查询窗口执行: SHOW VARIABLES LIKE 'event_scheduler' 查看是OFF 还是ON; 方式1: 修改.int配置文件 添加一行: event_scheduler ...

  2. Spring @Trasactionl 失效, JDK,CGLIB动态代理

    @Transaction:  http://blog.csdn.net/bao19901210/article/details/41724355 Spring上下文:  http://blog.csd ...

  3. 转载:canal数据库同步redis

    ref: http://blog.csdn.net/tb3039450/article/details/53928351

  4. ubuntu 安装u盘恢复

    XP下进入CMD命令窗体,Vista及7/8下右键以管理员方式运行DOS窗体(win8.1:开始屏幕-windows系统-命令提示符) 输入DISKPART,会显示计算机名,及DISKPART> ...

  5. 第一个struct2程序

    [第1步] 安装Struts2 这一步对于Struts1.x和Struts2都是必须的,只是安装的方法不同.Struts1的入口点是一个Servlet,而Struts2的入口点是一个过滤器(Filte ...

  6. scala 2.11.6 卸载 2.12.6 安装

    .yum remove scala .安装scala wget -O scala-.rpm https://downloads.lightbend.com/scala/2.12.6/scala-2.1 ...

  7. IRanges package

    1)介绍 在分析序列时,我们通常对特定的连续子序列感兴趣. 例如,a矢量可以被认为是按字母顺序排列的小写字母序列. 我们将第一个五个字母(a到e)称为连续的子序列,而仅包含元音的子序列不会是连续的. ...

  8. UNITY中的MOUSE点击事件的判断和AS3中的异同

    UNITY - 在UPDATE中轮询检测 Update() { if(Input.GetButton("Fire1") } AS3 - 事件监听 addEventListener. ...

  9. Ubuntu安装libevent

    背景: 版本: libevent 2.1.6beta linux下: 按照github官方做法: $ sudo apt-get install openssl $ mkdir build && ...

  10. anaconda+theano+keras手写字符识别新版

    标题介绍运行环境了win7 看网上好多keras识别minist 但是一般由于版本问题,无法直接用,,,这里还要特别感谢keras中文文档作者(三当家SCP).教程整的非常好.还有就是最好你在安装an ...