stark组件开发之添加按钮显示和URL
添加:
需求: 根据用户的权限, 决定是否,有添加按钮。 通过配置进行定制,预留钩子进行权限的判断。
class StartHandler(object):
..................... has_add_btn = True # 指定配置,默认显示。 用户在子类中,自定制是否显示
def get_add_btn(self):
'''预留钩子,子类中重写该方法。 根据权限的判断是否显示添加按钮'''
if self.has_add_btn:
return "<a class='btn btn-primary'>添加</a>"
return None def check_list_view(self, request, *args, **kwargs):
# ################6. 处理添加按钮######################
add_btn = self.get_add_btn()
return render(request, "stark/changelist.html",
{"header_list": header_list, "data_list": data_list,
"body_list": body_list,
"pager": pager,
"add_btn": add_btn,
"search_list": search_list,
"search_value": search_value,
"action_dict": action_dict}) ..................
class UserInfoHandler(StartHandler):
list_display = ["name", "age", "depart", get_choice_txt("性别", "gender"), StartHandler.display_edit,
StartHandler.display_del]
has_add_btn = True # False就表示, 不显示添加按钮
get_add_btn(self): # 可以进行重写。 权限的判断,或者,重写样式
pass
如果感觉,默认的样式不好看!
可以在, 子类中, 重写get_add_btn() 方法。 返回一个,自己喜欢的样式的 a 标签。 就行了!
然后,就是这个 a 标签的, 路有问题了! 并且还要,携带上,本次请求的 GET 的数据。
老套路: 自定义一个反向解析的,函数:
def reverse_url(self):
'''用于反向生成url, 并且携带,get请求的参数,跳转到下一个网页'''
name = "%s:%s" % (self.site.namespace, self.get_add_url_name)
base_url = reverse(name)
# 记录原搜索条件
if not self.request.GET:
add_url = base_url
else:
param = self.request.GET.urlencode() # 获取到GET请求的,所有的参数。 ?page=1&age=20
new_query_dict = QueryDict(mutable=True)
new_query_dict["_filter"] = param
add_url = "%s?%s" % (base_url, new_query_dict.urlencode())
return add_url
这里最重要的一个就是, self.request 这个东西, 是从前端传过来的, 我在初始化函数里面,定义了一下。 但是 他从哪里传给我的初始化函数呢? 就是在,获取 URL 的时候。
def wrapper(self, func):
@functools.wraps(func) # 保留原函数的 原信息
def inner(request, *args, **kwargs): # 这个inner 就是,我的每一个视图函数了!
self.request = request
return func(request, *args, **kwargs)
return inner def get_urls(self):
partterns = [
re_path(r"list/$", self.wrapper(self.check_list_view), name=self.get_list_url_name),
re_path(r"add/$", self.wrapper(self.add_view), name=self.get_add_url_name),
re_path(r"change/(\d+)/$", self.wrapper(self.change_view), name=self.get_edit_url_name),
re_path(r"del/(\d+)/$", self.wrapper(self.delete_view), name=self.get_del_url_name),
]
为了避免麻烦, 使用了 闭包的方式。来做这件事!
解释一下:
def wrapper(self, func):
@functools.wraps(func) # 保留原函数的 原信息
def inner(request, *args, **kwargs): # 这个inner 就是,我的每一个视图函数了!
self.request = request
return func(request, *args, **kwargs)
return inner
self.wrapper(self.check_list_view) 这个函数的工作其实就是: 重新赋值。 装饰器的套路
self.check_list_view = self.wrapper(self.check_list_view) # self.check_list_view == inner 可以这么理解
self.wrapper的返回值是 inner 函数的内存地址。所以其实执行 self.check_list_view 就相当于执行的是 inner。
re_path() 这个django内部的函数。 认为 self.wrapper(self.check_list_view) 是一个视图函数。 所以会给他带上一个 request 的参数。
注:self.wrapper(self.check_list_view) 这个一位加了 括号, 所以会先执行。并返回 inner。 而re_path 认为inner 就是视图函数。
所以我才能够在 inner 这个函数这里, 直接收到这个 request 。 然后我就将他 赋值给了, __init__ 初始化函数中的。 self.request = None
这样这参数,就不再是 None 而是一个,带着从前端返回的,带有参数的 request 对象。
我就可以,在程序的, 其他地方。 使用这个参数。
整体结构,就是这样:
def get_add_btn(self):
'''预留钩子,子类中重写该方法。 根据权限的判断是否显示添加按钮'''
if self.has_add_btn:
# 根据别名反向生成, URL
add_url = self.reverse_url()
return "<a class='btn btn-primary' href='%s'>添加</a>" % add_url
return None def reverse_url(self):
'''用于反向生成url, 并且携带,get请求的参数,跳转到下一个网页'''
name = "%s:%s" % (self.site.namespace, self.get_add_url_name)
base_url = reverse(name)
# 记录原搜索条件
if not self.request.GET:
add_url = base_url
else:
param = self.request.GET.urlencode() # 获取到GET请求的,所有的参数。 ?page=1&age=20
new_query_dict = QueryDict(mutable=True)
new_query_dict["_filter"] = param
add_url = "%s?%s" % (base_url, new_query_dict.urlencode())
return add_url per_page = 10 # 默认每页显示,多少数据。 也可在子类中,自行定制 def check_list_view(self, request):
'''
列表查看页面
:param request:
:return:
'''
# self.request = request # 进入查看页面,为request赋值! 使其他地方可以用到!
list_display = self.get_list_display()
# 页面要显示的列 self.list_display 示例:['name', 'age', 'depart'] # 1. 制作表头, 就是每张表中,每个字段写的 verbose_name.。 如何获取到这个值呢?
# self.model_class._meta.get_field('name').verbose_name
header_list = [] # 表头
if list_display:
for key_or_func in list_display:
if isinstance(key_or_func, FunctionType): # 判断当前参数, 是一个字符串还是一个函数。
verbose_name = key_or_func(self, obj=None, is_header=True)
else:
verbose_name = self.model_class._meta.get_field(key_or_func).verbose_name
header_list.append(verbose_name)
else:
header_list.append(self.model_class._meta.model_name) # 2. 处理 从数据库 取到的数据 # 用户访问的表 self.model_class
# 2.1 ###############处理分页#################
'''1.根据用户访问页面,计算出索引的位置, 比如 page=3
2. 生成html页码
'''
all_count = self.model_class.objects.all().count()
query_params = request.GET.copy() # page=1&level=2
query_params._mutable = True # request.get中的值默认是不能被修改的。加上这句代码就可以修改了 pager = Pagination(
current_page=request.GET.get("page"), # 用户访问的当前叶
all_count=all_count, # 数据库一共有多少数据
base_url=request.path_info, # 所在的url 就是 ?page=1 之前的URL
# 用于保留,用户的请求信息,比如 level=2 被用户先选中。 那么分页后。因为查询的东西少了,分页也应该想要的减少,
# 但是level=2这个, 请求的信息!不能因为。分页的原因。而减少。
query_params=query_params,
per_page=self.per_page, # 每页显示多少数据。
) # 2.1 ###############处理表格#################
data_list = self.model_class.objects.all()[pager.start:pager.end] body_list = []
for row in data_list:
row_list = []
if list_display:
for key_or_func in list_display:
if isinstance(key_or_func, FunctionType):
# 这里is_header=False obj=row(数据库中循环的每一行的对象)
row_list.append(key_or_func(self, obj=row, is_header=False))
else:
row_list.append(getattr(row, key_or_func))
else:
row_list.append(row)
body_list.append(row_list)
# 3 ############# 处理添加按钮####################
add_btn = self.get_add_btn() # 在这里调用了!此方法! return render(request, "stark/changelist.html",
{"header_list": header_list, "data_list": data_list,
"body_list": body_list,
"pager": pager,
"add_btn": add_btn})
stark组件开发之添加按钮显示和URL的更多相关文章
- stark组件开发之添加功能实现
添加功能,还是使用, form 组件来完成! 并且 完成添加之后,需要保留原搜索条件. def memory_url(self): '''用于反向生成url, 并且携带,get请求的参数,跳转到下一 ...
- stark组件开发之列表页面定制列
先看一张页面展示的效果图: 看一看我的 model 表!是什么样子: 看一看数据库是什么样子: 看 页面展示图,有表头. 有数据.模型表中,每一个字段, 都指定了 verbose_name. 如何解 ...
- 7 stark组件介绍、配置、2层url
1.django的admin配置 model.py from django.db import models # Create your models here. class UserInfo(mod ...
- 12 stark组件之pop,按钮,url,页面
1.Window open() 方法 http://www.runoob.com/jsref/met-win-open.html 效果图 2.admin的pop添加按钮 3.stark之pop功能 ...
- stark组件开发之批量操作
class UserInfoHandler(StartHandler): ....... # 批量操作功能的列表,添加则显示, 使用此功能.需要将StartHandler.display_checkb ...
- stark组件开发之列表页面应用示例
已经解决的,自定义的扩展函数,功能.但是 不可能返回. 一个 固定的页面把! 应该是,点击那条 记录之后的编辑, 就会跳转到相应的,编辑页面.所以 这个标签的 <a href="/ ...
- stark组件(1):动态生成URL
项目启动时自动生成URL 效果图: 知识点: Django启动前通过apps下的ready方法执行一个可以生成URL的py文件 include函数主要返回有三个元素的一个元组.第一个是url配置(ur ...
- stark组件开发之组合搜索高级显示和扩展
上一篇,我只是做了. 默认的显示. def __iter__(self): '''默认显示. 用户可以自定制''' if isinstance(self.queryset_or_tuple, list ...
- stark组件开发之列表页面预留钩子方法。 可根据用户的不同,显示不同的列
要实现,这个方法.子类中 list_diplay 这个列表, 就不能够写死.他应该是 可以根据.用户的不同,返回不同的值. 所以 就需要一个函数, 可以进行判断当前用户是谁. 并且往这个列表中添加,他 ...
随机推荐
- paramiko实现上传目录
使用paramiko上传目录,重点是上传的那个过程,想了一上午才想出来,可能有点奇葩,但是还是实现了这个功能 #!/usr/bin/python import paramiko import os d ...
- vagrant up报错 Warning: Authentication failure. Retrying...解决方案
参照链接 https://www.cnblogs.com/zqifa/p/vagrant-1.html 可以解决问题.
- SpringBoot配置(1) 配置文件application&yml
SpringBoot配置(1) 配置文件application&yml 一.配置文件 1.1 配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的. application ...
- 【docker】将Java jar文件生成镜像、上传镜像并生成镜像压缩文件
概述 将Springboot的web服务打包成Jar包后,自动化脚本将jar打包成镜像.上传镜像.并生成镜像的压缩文件: Dockerfile FROM 10.254.9.21/library/ora ...
- 把已经安装到C盘的软件完美移动到D盘
背景信息 今天早上在安装软件的时候发现C盘爆满,只剩下最后10G了.而我要安装的玩意儿必须装到C盘. 靠清理垃圾文件来解决并不是一个好方法,实际上通常垃圾文件占用很少,而且就算清理了,也还会再出现. ...
- denyhosts、中文文档乱码、端口占用查询
1.安装 denyhosts, 设置 hosts.allow ,系统自动将攻击的ip 添加如 hosts.deny2.打开中文文档乱码, 将文档下载到windows, 通过富文本编辑器查看文档编码3. ...
- Oauth2.0(三):Access Token 与 Refresh Token
access token 是客户端访问资源服务器的令牌.拥有这个令牌代表着得到用户的授权.然而,这个授权应该是临时的,有一定有效期.这是因为,access token 在使用的过程中可能会泄露.给 a ...
- jdbc与TiDB数据库交互的过程
以下是使用jdbc操作TiDB数据库,得到的交互过程和指令的说明 ==>代表发送给数据库的指令 // 加载驱动程序Class.forName(driver); // 连接数据库 Connecti ...
- RF:操作笔记
1.变量运算
- 63.(原65)纯 CSS 创作一个摇摇晃晃的 loader
原文地址:https://segmentfault.com/a/1190000015424389 修改后地址:https://scrimba.com/c/cqKv4VCR HTML code: < ...