优化代码

1:页面的增删改查url反转的封装到类里:ModelSatrk

  1. # 编辑页面的url
  2. def get_edit_url(self,obj):
  3. edit_url = reverse("%s_%s_change" % self.app_model_name,args=(obj.pk,))
  4. return edit_url
  5. # 删除页面url
  6. def get_delete_url(self,obj):
  7. del_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
  8. return del_url
  9.  
  10. def get_add_url(self,obj):
  11. add_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
  12. return add_url
  13.  
  14. def get_list_url(self,obj):
  15. list_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
  16. return list_url

2:显示页面的编辑和删除按钮

  1. # 编辑按钮
  2. def edit(self,obj=None,is_header=False):
  3. if is_header:
  4. return "操作"
  5. return mark_safe("<a href='%s'>编辑</a>"%self.get_edit_url(obj))
  6.  
  7. # return 的url需要反向解析,需要取到name的值
  8.  
  9. # 删除按钮
  10. def delete(self,obj=None,is_header=False):
  11. if is_header:
  12. return "操作"
  13. # 如何反向解析url
  14. return mark_safe("<a href='%s'>删除</a>"%self.get_delete_url(obj))

增删改查页面

  1. # 使用modelform 处理的基本流程
  2. 添加页面:
  3. get请求:
  4. form=UserModelForm()------>渲染表单标签
  5. post请求:
  6. form=UserModelForm(data=request.POST)
  7. if form.is_valid():
  8. form.save()-------->create一条记录
  9. 编辑页面:
  10. get请求:
  11. edit_obj=User.objects.filter(pk=id).first()
  12. form=UserModelForm(instance=edit_obj)------>渲染表单标签
  13. post请求:
  14. edit_obj=User.objects.filter(pk=id).first()
  15. form=UserModelForm(data=request.POST,instance=edit_obj)
  16. if form.is_valid():
  17. form.save()-------->对edit_obj的数据更新为request.POST

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>Title</title>
  8. </head>
  9. <body>
  10. <h3>添加数据</h3>
  11.  
  12. <form action="" method="post" novalidate>
  13. {% csrf_token %}
  14. {{ form.as_p }}
  15. <input type="submit" value="submit">
  16. </form>
  17.  
  18. </body>
  19. </html>

html

需要后端展示页面传值

  1. add_url=self.get_add_url()

增的页面表单第二种渲染方式

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>Title</title>
  8. <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
  9. <style>
  10. .form-group .input_style input {
  11. display: block;
  12. width: 100%;
  13. height: 34px;
  14. padding: 6px 12px;
  15. font-size: 14px;
  16. line-height: 1.42857143;
  17. color: #555;
  18. background-color: #fff;
  19. background-image: none;
  20. border: 1px solid #ccc;
  21. border-radius: 4px;
  22. -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  23. box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  24. -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
  25. -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  26. transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  27. }
  28.  
  29. .error {
  30. color: red;
  31. }
  32. </style>
  33. </head>
  34. <body>
  35. <h3>添加数据</h3>
  36. {# 第一种渲染表单方式 #}
  37. {#<form action="" method="post" novalidate>#}
  38. {# {% csrf_token %}#}
  39. {# {{ form.as_p }}#}
  40. {# <input type="submit" value="submit">#}
  41. {#</form>#}
  42. {# 第三种渲染表单方式 #}
  43. <div class="container">
  44. <div class="row">
  45. <div class="col-md-6">
  46. <form action="" method="post" novalidate>
  47. {% csrf_token %}
  48. {% for field in form %}
  49. <div class="form-group">
  50. <label for="">{{ field.label }}</label>
  51. <div class="input_style">
  52. {{ field }}
  53. <span class="error pull-right">{{ field.errors.0 }}</span>
  54. </div>
  55. </div>
  56. {% endfor %}
  57.  
  58. <p><input type="submit" class="btn btn-default " value="提交"></p>
  59. </form>
  60.  
  61. </div>
  62. </div>
  63. </div>
  64.  
  65. </body>
  66. </html>

关于显示错误信息

1:用户定制了(显示中文的)

2:用户没有定义(显示英文)

需要添加 model_form_class=None 变量来判断当前用户有没有定义信息

  1. from django.utils.safestring import mark_safe
  2. from django.urls import reverse
  3. from django.forms import ModelForm
  4. #
  5. class BookModelForm(ModelForm):
  6. class Meta:
  7. model=Book
  8. fields='__all__' # 展示字段
  9. error_messages={ # 针对book表的error_messages
  10. "title":{"required":"不能为空"},
  11. "price":{"required":"不能为空"},
  12. }
  13.  
  14. class BookConfig(ModelSatrk):
  15. list_display = ["id","title","price",] # z这个list_display只针对Book表
  16. model_form_class=BookModelForm # 当用户定制显示信息,就自己定制的,没有用默认
  17. # 自制注册功能(admin表的注册
  18.  
  19. site.register(Book,BookConfig)

stark

  1. # 添加页面视图
  2. def add_view(self,request):
  3. # 基于modelform
  4. # 先走用户的(如果用户写了这个名字,就用用户的) 如果为空既是用户没有定制显示信息
  5. if not self.model_form_class: # 用父类
  6. ModelFormClass=self.get_modelform_class()
  7. else: # 用户定义了
  8. ModelFormClass=self.model_form_class
  9.  
  10. if request.method=="GET":
  11. form=ModelFormClass() # 取到当前表数据(渲染表单表单)
  12. return render(request,"stark/add_view.html",{"form":form})
  13. else:
  14. form=ModelFormClass(data=request.POST)
  15. if form.is_valid(): # is_valid 判断当前数据通不通过
  16. form.save() # 新建一条数据
  17. return redirect(self.get_list_url())
  18. else: # 数据有问题
  19. return render(request, "stark/add_view.html", {"form":form})

优化(这部分代码在下面重复调用较多)

  1. if not self.model_form_class: # 用父类
  2. ModelFormClass=self.get_modelform_class()
  3. else: # 用户定义了
  4. ModelFormClass=self.model_form_class

把他封装到类里面

  1. # 添加页面视图
  2. def add_view(self,request):
  3. # 基于modelform
  4.  
  5. ModelFormClass=self.model_form_class
  6. if request.method=="GET":
  7. form=ModelFormClass() # 取到当前表数据(渲染表单表单)
  8. return render(request,"stark/add_view.html",{"form":form})
  9. else:
  10. form=ModelFormClass(data=request.POST)
  11. if form.is_valid(): # is_valid 判断当前数据通不通过
  12. form.save() # 新建一条数据
  13. return redirect(self.get_list_url())
  14. else: # 数据有问题
  15. return render(request, "stark/add_view.html", {"form":form})
  16.  
  17. # 编辑视图
  18. def change_view(self,request,id):
  19. edit_book = self.model.objects.filter(pk=id).first() # 取到要修改的数据对象
  20. ModelFormClass = self.model_form_class
  21. form = ModelFormClass(instance=edit_book) # 需要编辑的内容
  22. if request.method=="GET":
  23. form=ModelFormClass(instance=edit_book)
  24. return render(request,"stark/change_view.html",{"form":form})
  25. else:
  26. form=ModelFormClass(data=request.POST,instance=edit_book)
  27. if form.is_valid():
  28. form.save()
  29. return redirect("/index/")
  30. return render(request,"stark/change_view.html",{"form":form})

修改的两个视图

优化二:添加页面和编辑页面基本相同 利用

  1. include

相同部分放到一个form.html里面

  1. <div class="container">
  2. <div class="row">
  3. <div class="col-md-6">
  4. <form action="" method="post" novalidate>
  5. {% csrf_token %}
  6. {% for field in form %}
  7. <div class="form-group">
  8. <label for="">{{ field.label }}</label>
  9. <div class="input_style">
  10. {{ field }}
  11. <span class="error pull-right">{{ field.errors.0 }}</span>
  12. </div>
  13. </div>
  14. {% endfor %}
  15.  
  16. <p><input type="submit" class="btn btn-default " value="提交"></p>
  17. </form>
  18.  
  19. </div>
  20. </div>
  21. </div>

调用

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>Title</title>
  8. <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
  9. <style>
  10. .form-group .input_style input {
  11. display: block;
  12. width: 100%;
  13. height: 34px;
  14. padding: 6px 12px;
  15. font-size: 14px;
  16. line-height: 1.42857143;
  17. color: #555;
  18. background-color: #fff;
  19. background-image: none;
  20. border: 1px solid #ccc;
  21. border-radius: 4px;
  22. -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  23. box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  24. -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
  25. -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  26. transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  27. }
  28.  
  29. .error {
  30. color: red;
  31. }
  32. </style>
  33. </head>
  34. <body>
  35. <h3>添加数据</h3>
  36. {# 第一种渲染表单方式 #}
  37. {#<form action="" method="post" novalidate>#}
  38. {# {% csrf_token %}#}
  39. {# {{ form.as_p }}#}
  40. {# <input type="submit" value="submit">#}
  41. {#</form>#}
  42. {# 第三种渲染表单方式 #}
  43. {% include 'stark/form.html' %}
  44.  
  45. </body>
  46. </html>

add

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>Title</title>
  8. <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
  9. <style>
  10. .form-group .input_style input {
  11. display: block;
  12. width: 100%;
  13. height: 34px;
  14. padding: 6px 12px;
  15. font-size: 14px;
  16. line-height: 1.42857143;
  17. color: #555;
  18. background-color: #fff;
  19. background-image: none;
  20. border: 1px solid #ccc;
  21. border-radius: 4px;
  22. -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  23. box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  24. -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
  25. -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  26. transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  27. }
  28.  
  29. .error {
  30. color: red;
  31. }
  32. </style>
  33. </head>
  34. <body>
  35. <h3>添加数据</h3>
  36. {# 第一种渲染表单方式 #}
  37. {#<form action="" method="post" novalidate>#}
  38. {# {% csrf_token %}#}
  39. {# {{ form.as_p }}#}
  40. {# <input type="submit" value="submit">#}
  41. {#</form>#}
  42. {# 第三种渲染表单方式 #}
  43. {% include 'stark/form.html' %}
  44.  
  45. </body>
  46. </html>

change

需求:将指定字段名变成有链接-----list_display_links

  问题:分为2中情况,1:当有用户定义,用用户的  2、当用户没有定义,就用默认的

  1. # 3 完成注册
  2. from stark.service.site import site,ModelSatrk
  3.  
  4. from .models import *
  5. from django.utils.safestring import mark_safe
  6. from django.urls import reverse
  7. from django.forms import ModelForm
  8. #
  9. class BookModelForm(ModelForm):
  10. class Meta:
  11. model=Book
  12. fields='__all__' # 展示字段
  13. error_messages={ # 针对book表的error_messages
  14. "title":{"required":"不能为空"},
  15. "price":{"required":"不能为空"},
  16. }
  17.  
  18. # list_display只针对Book表
  19. class BookConfig(ModelSatrk):
  20. list_display = ["id","title","price",] # 用户用于页面显示的字段
  21. model_form_class=BookModelForm # 当用户定制显示错误信息,就自己定制的,没有用默认
  22. list_display_links = ["title"] # 用户用于定制添加跳转编辑页面字段
  23. # 自制注册功能(admin表的注册
  24.  
  25. site.register(Book,BookConfig)

stark

  1. # 展示数据
  2. def show_list_view(self,request):
  3. print("self.model",self.model) # 打印当前表
  4. # 生成表表头
  5. header_list=[]
  6. for field in self.get_list_display(): # ["id","title","price","edit"]
  7. if callable(field):
  8. # header_list.append(field.__name__)
  9. val = field(self,is_header=True) # 定义了一个is_header=True变量
  10. header_list.append(val)
  11. else:
  12. if field=="__str__": # 默认样式
  13. header_list.append(self.model._meta.model_name.upper())
  14. else:
  15. field_obj=self.model._meta.get_field(field)
  16. header_list.append(field_obj.verbose_name) # verbose_name 显示描述字段
  17.  
  18. # 生成表单部分 # header_list:["ID","标题","价格","操作"]
  19. data_list = self.model.objects.all() # 去数据库取来的所有数据 对象
  20. print("self.list_display",self.list_display) # 用户定义了self.list_display ['id', 'title', 'price']
  21. # 用户没有定义self.list_display[]
  22. # 做成下面我们想要的数据格式
  23. new_data_list=[] # 渲染页面的数据
  24. for obj in data_list: # obj:当前每本书的对象
  25. temp=[]
  26. # 当用户定义了list_display的情况 利用反射求值
  27. for field in self.get_list_display(): # ['id', 'title', 'price',delete,edit] ,
  28. if callable(field): # 当遇到delete,edit函数
  29. val=field(self,obj) # 执行函数返回的返回值
  30. else: # 'id', 'title', 'price'
  31. val=getattr(obj,field) # 利用反射getattr取值 当用户没定义list_display用“__str__”
  32. # 选择指定字段添加a标签跳转到edit页面
  33. if field in self.list_display_links:
  34. val=mark_safe("<a href='%s'>%s</a>"%(self.get_edit_url(obj),val))
  35.  
  36. temp.append(val) # 当走默认的话,也会把__str__传到val
  37. new_data_list.append(temp)
  38. print(new_data_list) # [[1, '《看见》---柴静', Decimal('12.00')], [2, '《围城》---钱钟书', Decimal('12.00')]]
  39.  
  40. # 添加新的标签:
  41. # [
  42. # [1, '《看见》---柴静', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"],
  43. # [2, '《围城》---钱钟书', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"]
  44. # ]
  45. # '''
  46. # [
  47. # [1,"xxx"],
  48. # [2,"xxxxx"],
  49. # [3,"xxxxxxx'],
  50. # ]
  51. # '''
  52. add_url=self.get_add_url()
  53. return render(request,"stark/show_list.html",locals())

site

  

  需求2:当用户指定了添加跳转编辑页面的字段时,将不显示操作的编辑

思路:找到哪里显示了编辑按钮

只需要修改下面逻辑

需要跳转到让用户选择肯定或取消

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>删除页面</title>
  8. <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
  9. </head>
  10. <body>
  11. {# 将要删除的数据取出来 #}
  12. <div>
  13. <p>{{ del_obj }}</p></div>
  14. <form action="" method="post">
  15. {% csrf_token %}
  16.  
  17. <input type="submit" class="btn btn-danger" value="确认删除吗?">
  18. <a href="{{ list_url }}" class="btn btn-info">取消</a>
  19. </form>
  20.  
  21. </body>
  22. </html>

HTML

  1. # 删除视图
  2. def del_view(self,request,id):
  3. # 先取到要删除的对象、
  4. del_obj = self.model.objects.filter(pk=id).first()
  5. if request.method=="GET":
  6. list_url = self.get_list_url()
  7. return render(request,"stark/del_view.html",{"del_obj":del_obj , "list_url":list_url})
  8. else:
  9. del_obj.delete() # 将需要删除的对象删除
  10. return redirect(self.get_list_url()) # 跳转回显示页面

接下来需要添加的功能

  1. 查看页面:
  2. ---
  3. 分页器
  4. search
  5. action
  6. fliter

stark组件03的更多相关文章

  1. Python-S9-Day88——stark组件之设计urls

    03 stark组件之设计urls 04 stark组件之设计urls2 05 stark组件之设计list_display 06 stark组件之z查看页面的数据展示 03 stark组件之设计ur ...

  2. 【django之stark组件】

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

  3. django 之 stark组件

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

  4. 设计stark组件

    设计stark组件 作者:Eric 微信:loveoracle11g 新建Django项目crm_1随便起名 然后再创建一个App manage.py@crm_1 > startapp star ...

  5. stark组件的分页,模糊查询,批量删除

    1.分页组件高阶 2.整合展示数据showlist类 3.stark组件之分页 3.stark组件之search模糊查询 4.action批量处理数据 4.总结 1.分页组件高阶 1.分页的class ...

  6. stark组件配置,二层URL

    1.django的admin配置 2 stark组件开发 3.2层url分发 4.小结 1.django的admin配置 model.py from django.db import models # ...

  7. CRM项目之stark组件

    . stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...

  8. stark组件开发之列表页面应用示例

    已经解决的,自定义的扩展函数,功能.但是 不可能返回. 一个 固定的页面把!  应该是,点击那条 记录之后的编辑, 就会跳转到相应的,编辑页面.所以 这个标签的  <a href="/ ...

  9. Django之stark组件

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

随机推荐

  1. SQLite-C#-帮助类

    public static class SQLiteHelper { private static string connectionString = string.Empty; #region vo ...

  2. Android -- 文件上传到服务器

    1. 文件上传的两种方式 (1) HttpClient (2)AsyncHttpClient (开源框架: https://github.com/loopj/android-async-http) 示 ...

  3. ubuntu16.04 安装power shell

    ubuntu16.04 安装power shell # Download the Microsoft repository GPG keys wget -q https://packages.micr ...

  4. SPA(单页面web应用程序)

    单页web应用(single page web application,SPA),就是只有一张web页面的应用,是加载单个HTML页面并在用户与应用程序交互时动态更新该页面的web应用程序. 浏览器一 ...

  5. ArrayBuffer

    ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.这些对象早就存在,属于独立的规格(2011 年 2 月发布),ES6 将它 ...

  6. spark 性能优化

    1.内存 spark.storage.memoryFraction:很明显,是指spark缓存的大小,默认比例0.6 spark.shuffle.memoryFraction:管理executor中R ...

  7. tensorflow 模型保存

    1.首先 saver = tf.train.Saver(max_to_keep=1)新建一个saver,max_to_keep是说只保留最后一轮的训练结果 2.使用save方法保存模型 saver.s ...

  8. FastDFS图片服务器

    首先要转一个FastDFS,这个很难装.一般由运维人员安装. git项目fastdfs-client-java由happy fish开发的,down下来后import到项目中maven install ...

  9. eclipse使用lombok

    1.下载lombok.jar,将lombok复制到eclipse的安装路径下,如图: 2.在eclipse.ini配置文件最后加入:-javaagent:D:\Program Files\Eclips ...

  10. 新男人八题---AStringGame

    终于完成进度男人1/8,为了这题学了sam= = 题意先有一个串,n个子串,两个人轮流每次在子串上加字符,要求加完后还是原串的子串,最后不能加的就是输者,求赢的人 解法:sam之后在构造的状态图上跑s ...