stark组件03
优化代码
1:页面的增删改查url反转的封装到类里:ModelSatrk
# 编辑页面的url
def get_edit_url(self,obj):
edit_url = reverse("%s_%s_change" % self.app_model_name,args=(obj.pk,))
return edit_url
# 删除页面url
def get_delete_url(self,obj):
del_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
return del_url def get_add_url(self,obj):
add_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
return add_url def get_list_url(self,obj):
list_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
return list_url
2:显示页面的编辑和删除按钮
# 编辑按钮
def edit(self,obj=None,is_header=False):
if is_header:
return "操作"
return mark_safe("<a href='%s'>编辑</a>"%self.get_edit_url(obj)) # return 的url需要反向解析,需要取到name的值 # 删除按钮
def delete(self,obj=None,is_header=False):
if is_header:
return "操作"
# 如何反向解析url
return mark_safe("<a href='%s'>删除</a>"%self.get_delete_url(obj))
增删改查页面
# 使用modelform 处理的基本流程
添加页面:
get请求:
form=UserModelForm()------>渲染表单标签
post请求:
form=UserModelForm(data=request.POST)
if form.is_valid():
form.save()-------->create一条记录
编辑页面:
get请求:
edit_obj=User.objects.filter(pk=id).first()
form=UserModelForm(instance=edit_obj)------>渲染表单标签
post请求:
edit_obj=User.objects.filter(pk=id).first()
form=UserModelForm(data=request.POST,instance=edit_obj)
if form.is_valid():
form.save()-------->对edit_obj的数据更新为request.POST
增
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h3>添加数据</h3> <form action="" method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="submit">
</form> </body>
</html>
html
需要后端展示页面传值
add_url=self.get_add_url()
增的页面表单第二种渲染方式
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
<style>
.form-group .input_style input {
display: block;
width: 100%;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
} .error {
color: red;
}
</style>
</head>
<body>
<h3>添加数据</h3>
{# 第一种渲染表单方式 #}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# {{ form.as_p }}#}
{# <input type="submit" value="submit">#}
{#</form>#}
{# 第三种渲染表单方式 #}
<div class="container">
<div class="row">
<div class="col-md-6">
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="">{{ field.label }}</label>
<div class="input_style">
{{ field }}
<span class="error pull-right">{{ field.errors.0 }}</span>
</div>
</div>
{% endfor %} <p><input type="submit" class="btn btn-default " value="提交"></p>
</form> </div>
</div>
</div> </body>
</html>
关于显示错误信息
1:用户定制了(显示中文的)
2:用户没有定义(显示英文)
需要添加 model_form_class=None 变量来判断当前用户有没有定义信息
from django.utils.safestring import mark_safe
from django.urls import reverse
from django.forms import ModelForm
#
class BookModelForm(ModelForm):
class Meta:
model=Book
fields='__all__' # 展示字段
error_messages={ # 针对book表的error_messages
"title":{"required":"不能为空"},
"price":{"required":"不能为空"},
} class BookConfig(ModelSatrk):
list_display = ["id","title","price",] # z这个list_display只针对Book表
model_form_class=BookModelForm # 当用户定制显示信息,就自己定制的,没有用默认
# 自制注册功能(admin表的注册 site.register(Book,BookConfig)
stark
# 添加页面视图
def add_view(self,request):
# 基于modelform
# 先走用户的(如果用户写了这个名字,就用用户的) 如果为空既是用户没有定制显示信息
if not self.model_form_class: # 用父类
ModelFormClass=self.get_modelform_class()
else: # 用户定义了
ModelFormClass=self.model_form_class if request.method=="GET":
form=ModelFormClass() # 取到当前表数据(渲染表单表单)
return render(request,"stark/add_view.html",{"form":form})
else:
form=ModelFormClass(data=request.POST)
if form.is_valid(): # is_valid 判断当前数据通不通过
form.save() # 新建一条数据
return redirect(self.get_list_url())
else: # 数据有问题
return render(request, "stark/add_view.html", {"form":form})
优化(这部分代码在下面重复调用较多)
if not self.model_form_class: # 用父类
ModelFormClass=self.get_modelform_class()
else: # 用户定义了
ModelFormClass=self.model_form_class
把他封装到类里面
# 添加页面视图
def add_view(self,request):
# 基于modelform ModelFormClass=self.model_form_class
if request.method=="GET":
form=ModelFormClass() # 取到当前表数据(渲染表单表单)
return render(request,"stark/add_view.html",{"form":form})
else:
form=ModelFormClass(data=request.POST)
if form.is_valid(): # is_valid 判断当前数据通不通过
form.save() # 新建一条数据
return redirect(self.get_list_url())
else: # 数据有问题
return render(request, "stark/add_view.html", {"form":form}) # 编辑视图
def change_view(self,request,id):
edit_book = self.model.objects.filter(pk=id).first() # 取到要修改的数据对象
ModelFormClass = self.model_form_class
form = ModelFormClass(instance=edit_book) # 需要编辑的内容
if request.method=="GET":
form=ModelFormClass(instance=edit_book)
return render(request,"stark/change_view.html",{"form":form})
else:
form=ModelFormClass(data=request.POST,instance=edit_book)
if form.is_valid():
form.save()
return redirect("/index/")
return render(request,"stark/change_view.html",{"form":form})
修改的两个视图
优化二:添加页面和编辑页面基本相同 利用
include
相同部分放到一个form.html里面
<div class="container">
<div class="row">
<div class="col-md-6">
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="">{{ field.label }}</label>
<div class="input_style">
{{ field }}
<span class="error pull-right">{{ field.errors.0 }}</span>
</div>
</div>
{% endfor %} <p><input type="submit" class="btn btn-default " value="提交"></p>
</form> </div>
</div>
</div>
调用
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
<style>
.form-group .input_style input {
display: block;
width: 100%;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
} .error {
color: red;
}
</style>
</head>
<body>
<h3>添加数据</h3>
{# 第一种渲染表单方式 #}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# {{ form.as_p }}#}
{# <input type="submit" value="submit">#}
{#</form>#}
{# 第三种渲染表单方式 #}
{% include 'stark/form.html' %} </body>
</html>
add
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
<style>
.form-group .input_style input {
display: block;
width: 100%;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
} .error {
color: red;
}
</style>
</head>
<body>
<h3>添加数据</h3>
{# 第一种渲染表单方式 #}
{#<form action="" method="post" novalidate>#}
{# {% csrf_token %}#}
{# {{ form.as_p }}#}
{# <input type="submit" value="submit">#}
{#</form>#}
{# 第三种渲染表单方式 #}
{% include 'stark/form.html' %} </body>
</html>
change
需求:将指定字段名变成有链接-----list_display_links
问题:分为2中情况,1:当有用户定义,用用户的 2、当用户没有定义,就用默认的
# 3 完成注册
from stark.service.site import site,ModelSatrk from .models import *
from django.utils.safestring import mark_safe
from django.urls import reverse
from django.forms import ModelForm
#
class BookModelForm(ModelForm):
class Meta:
model=Book
fields='__all__' # 展示字段
error_messages={ # 针对book表的error_messages
"title":{"required":"不能为空"},
"price":{"required":"不能为空"},
} # list_display只针对Book表
class BookConfig(ModelSatrk):
list_display = ["id","title","price",] # 用户用于页面显示的字段
model_form_class=BookModelForm # 当用户定制显示错误信息,就自己定制的,没有用默认
list_display_links = ["title"] # 用户用于定制添加跳转编辑页面字段
# 自制注册功能(admin表的注册 site.register(Book,BookConfig)
stark
# 展示数据
def show_list_view(self,request):
print("self.model",self.model) # 打印当前表
# 生成表表头
header_list=[]
for field in self.get_list_display(): # ["id","title","price","edit"]
if callable(field):
# header_list.append(field.__name__)
val = field(self,is_header=True) # 定义了一个is_header=True变量
header_list.append(val)
else:
if field=="__str__": # 默认样式
header_list.append(self.model._meta.model_name.upper())
else:
field_obj=self.model._meta.get_field(field)
header_list.append(field_obj.verbose_name) # verbose_name 显示描述字段 # 生成表单部分 # header_list:["ID","标题","价格","操作"]
data_list = self.model.objects.all() # 去数据库取来的所有数据 对象
print("self.list_display",self.list_display) # 用户定义了self.list_display ['id', 'title', 'price']
# 用户没有定义self.list_display[]
# 做成下面我们想要的数据格式
new_data_list=[] # 渲染页面的数据
for obj in data_list: # obj:当前每本书的对象
temp=[]
# 当用户定义了list_display的情况 利用反射求值
for field in self.get_list_display(): # ['id', 'title', 'price',delete,edit] ,
if callable(field): # 当遇到delete,edit函数
val=field(self,obj) # 执行函数返回的返回值
else: # 'id', 'title', 'price'
val=getattr(obj,field) # 利用反射getattr取值 当用户没定义list_display用“__str__”
# 选择指定字段添加a标签跳转到edit页面
if field in self.list_display_links:
val=mark_safe("<a href='%s'>%s</a>"%(self.get_edit_url(obj),val)) temp.append(val) # 当走默认的话,也会把__str__传到val
new_data_list.append(temp)
print(new_data_list) # [[1, '《看见》---柴静', Decimal('12.00')], [2, '《围城》---钱钟书', Decimal('12.00')]] # 添加新的标签:
# [
# [1, '《看见》---柴静', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"],
# [2, '《围城》---钱钟书', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"]
# ]
# '''
# [
# [1,"xxx"],
# [2,"xxxxx"],
# [3,"xxxxxxx'],
# ]
# '''
add_url=self.get_add_url()
return render(request,"stark/show_list.html",locals())
site
需求2:当用户指定了添加跳转编辑页面的字段时,将不显示操作的编辑
思路:找到哪里显示了编辑按钮
只需要修改下面逻辑
删
需要跳转到让用户选择肯定或取消
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>删除页面</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body>
{# 将要删除的数据取出来 #}
<div>
<p>{{ del_obj }}</p></div>
<form action="" method="post">
{% csrf_token %} <input type="submit" class="btn btn-danger" value="确认删除吗?">
<a href="{{ list_url }}" class="btn btn-info">取消</a>
</form> </body>
</html>
HTML
# 删除视图
def del_view(self,request,id):
# 先取到要删除的对象、
del_obj = self.model.objects.filter(pk=id).first()
if request.method=="GET":
list_url = self.get_list_url()
return render(request,"stark/del_view.html",{"del_obj":del_obj , "list_url":list_url})
else:
del_obj.delete() # 将需要删除的对象删除
return redirect(self.get_list_url()) # 跳转回显示页面
接下来需要添加的功能
查看页面:
---
分页器
search
action
fliter
stark组件03的更多相关文章
- Python-S9-Day88——stark组件之设计urls
03 stark组件之设计urls 04 stark组件之设计urls2 05 stark组件之设计list_display 06 stark组件之z查看页面的数据展示 03 stark组件之设计ur ...
- 【django之stark组件】
一.需求 仿照django的admin,开发自己的stark组件.实现类似数据库客户端的功能,对数据进行增删改查. 二.实现 1.在settings配置中分别注册这三个app # Applicatio ...
- django 之 stark组件
----------------------------------------------------------------烦恼没完没了,内心动荡不安,呜呼哀哉. 一.有个特殊的需求,需要用sta ...
- 设计stark组件
设计stark组件 作者:Eric 微信:loveoracle11g 新建Django项目crm_1随便起名 然后再创建一个App manage.py@crm_1 > startapp star ...
- stark组件的分页,模糊查询,批量删除
1.分页组件高阶 2.整合展示数据showlist类 3.stark组件之分页 3.stark组件之search模糊查询 4.action批量处理数据 4.总结 1.分页组件高阶 1.分页的class ...
- stark组件配置,二层URL
1.django的admin配置 2 stark组件开发 3.2层url分发 4.小结 1.django的admin配置 model.py from django.db import models # ...
- CRM项目之stark组件
. stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...
- stark组件开发之列表页面应用示例
已经解决的,自定义的扩展函数,功能.但是 不可能返回. 一个 固定的页面把! 应该是,点击那条 记录之后的编辑, 就会跳转到相应的,编辑页面.所以 这个标签的 <a href="/ ...
- Django之stark组件
现在让我说啥是stark组件,我也说不清楚.反正从今天讲的知识来看,今天完成的就是自己写一个模块,这个模块包含了admin后台管理工具的一些比较好用的功能,我们把它提炼出来,也就是相当于自己写一个ad ...
随机推荐
- VirtualBox安装RedHat7
软件准备 VirtualBox-5.2.8-121009-Win.exe rhel-server-7.4-x86_64-dvd.iso 安装环境 win10 安装步骤: 1.先在win10系统中安装V ...
- hdu5727
Necklace SJX has 2*N magic gems. N of them have Yin energy inside while others have Yang energy. SJX ...
- BZOJ3236: [AHOI2013]作业
BZOJ3236: [AHOI2013]作业 题目描述 传送门 行,我知道是Please contact lydsy2012@163.com! 传送门2 题目分析 这题两问还是非常,emmmm. 首先 ...
- [小问题笔记(十)] SQL Server 里 float 转 varchar等字符类型 不使用科学计数法
需要转换两次, 试了一下 float 转 bigint 转 varchar 溢出了... 后来用 float 转 decimal(38,0) 转 varchar 就成功了~ ,)) )) 另吐槽一下 ...
- harbor 管理Helm Chart包
官方网站:https://github.com/goharbor/harbor官方用户手册:https://github.com/goharbor/harbor/blob/master/docs/us ...
- java 之 find 命令
转自:https://blog.csdn.net/holyshit666/article/details/52296966 find命令是比较常用的命令,用来在特定目录下查找具有某种特征的文件. 一: ...
- 面试笔试总结(二)之 C++基础
上节,一定要写出基于引用计数的智能指针 明白单例模式 会写出代码 复习: 1- 2- 推荐leveldb ....是c++的写代码很规范的地方?比如智能指针在这里... 对类进行改造 可以改成Sing ...
- SSH密钥登陆免密码方法
原帖地址:http://ask.apelearn.com/question/798 用Putty实现A机器远程登陆B机器,具体实现请看链接:http://www.cnblogs.com/ImJerry ...
- 互联网公司面试必问的Redis题目
Redis是一个非常火的非关系型数据库,火到什么程度呢?只要是一个互联网公司都会使用到.Redis相关的问题可以说是面试必问的,下面我从个人当面试官的经验,总结几个必须要掌握的知识点. 介绍:Redi ...
- SPOJ MYQ10 (数位DP)
题意 询问区间[a,b]中的Mirror Number的个数,其中Mirror Number是指把它横着翻转后还能表示同样的数字. 思路 注意这个可不是回文数..除了0,1,8,别的数字翻转过后就不是 ...