stark——增删改页面
一、制作添加页面
1、前置准备
(1)修改增删改的视图函数名
1 2 3 4 5 6 7 8 9 10 | class ModelStark( object ): def add_view( self , request): return HttpResponse( "add" ) def delete_view( self , request, id ): return HttpResponse( "delete" ) def change_view( self , request, id ): return HttpResponse( "change" ) |
(2)调整路由对应的视图函数
1 2 3 4 5 6 7 8 9 10 11 12 13 | class ModelStark( object ): def get_urls_2( self ): temp = [] # 用name取别名app名+model名+操作名可以保证别名不会重复 model_name = self .model._meta.model_name app_label = self .model._meta.app_label temp.append(url(r "^add/" , self .add_view, name = "%s_%s_add" % (app_label, model_name))) temp.append(url(r "^(\d+)/delete/" , self .delete_view, name = "%s_%s_delete" % (app_label, model_name))) temp.append(url(r "^(\d+)/change/" , self .change_view, name = "%s_%s_change" % (app_label, model_name))) temp.append(url(r "^$" , self .list_view, name = "%s_%s_list" % (app_label, model_name))) return temp |
(3)在查看页面添加add按钮
首先在list_view中获取add_url:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class ModelStark( object ): '''代码省略''' def get_add_url( self ): model_name = self .model._meta.model_name app_label = self .model._meta.app_label _url = reverse( "%s_%s_add" % (app_label, model_name)) return _url def list_view( self , request): '''代码省略''' # 构建一个查看url add_url = self .get_add_url() return render(request, "list_view.html" , locals ()) |
在list_view.html中添加“添加数据”按钮:
1 2 3 4 5 6 7 8 9 10 | < body > < h4 >数据列表</ h4 > < div class="container"> < div class="row"> < div class="col-md-9"> {# < a href="add/" class="btn btn-primary">添加数据</ a > #} < a href="{{ add_url }}" class="btn btn-primary">添加数据</ a > """代码省略""" </ body > </ html > |
(4)重构模型
由于之前的表结构过于简单,在进行添加操作时很多问题无法发现,在这里重新构造模型(一对一、一对多、多对多都有)。

from django.db import models # Create your models here. class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() # 与AuthorDetail建立一对一的关系 authorDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE) def __str__(self): return self.name class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64) def __str__(self): return self.telephone class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors = models.ManyToManyField(to='Author', ) def __str__(self): return self.title
同时将app01/admin.py和app01/stark.py中的内容清空重新进行构建。
(5)删除数据重新进行数据库迁移
1)删除app01/migrations/下的文件
2)删除db.sqlite3
3)数据迁移
1 2 | manage.py@stark_demo > makemigrations manage.py@stark_demo > migrate |
(6)在stark中注册表:
app01/stark.py:
1 2 3 4 5 6 7 8 9 | from stark.service.stark import site, ModelStark from django.utils.safestring import mark_safe from django.urls import reverse from .models import * site.register(Book) site.register(Publish) site.register(Author) site.register(AuthorDetail) |
到此页面已经可以正常访问:
2、自定制配置modelform来构建添加页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class ModelStark( object ): def add_view( self , request): from django.forms import ModelForm from django.forms import widgets as wid class ModelFormDemo(ModelForm): class Meta: model = self .model fields = "__all__" # 不能使用这种方法,因为每个表的字段是不同的 # widgets = { # "title": wid.TextInput(attrs={"class": "form-control"}) # } form = ModelFormDemo() # 实例化 return render(request, "add_view.html" , locals ()) |
3、构建add_view.html模板

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery-1.12.4.min.js"></script> <style> input,select { 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; } </style> </head> <body> <h3>添加页面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form action="" method="post"> {% for field in form %} <div> <label for="">{{ field.label }}</label> {{ field }} </div> {% endfor %} <button type="submit" class="btn btn-default">提交</button> </form> </div> </div> </div> </body> </html>
由于每个表字段不同,因此不能使用wigets来给所有标签添加form-control样式,直接在页面用css给input\select构建form-control的样式。
显示效果如下所示:
4、给所有字段更换为中文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class ModelStark( object ): """默认类,定制配置类""" list_display = [ "__str__" ,] list_display_links = [] modelform_class = [] '''代码省略''' def get_modelform_class( self ): """用来获取modelform类""" if not self .modelform_class: # 如果没有值 from django.forms import ModelForm from django.forms import widgets as wid class ModelFormDemo(ModelForm): class Meta: model = self .model fields = "__all__" return ModelFormDemo else : # 如果有值说明在用户已经自己定制过了,直接取值 return self .modelform_class def add_view( self , request): ModelFormDemo = self .get_modelform_class() form = ModelFormDemo() # 实例化 return render(request, "add_view.html" , locals ()) |
(1)定义get_modelform_class方法来获取modelform类。如果在app01/stark.py中自定义配置类没有modelform_class,则默认为空,通过这个方法来获取modelform。
(2)自定义配置Book类,并将字段显示中文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from stark.service.stark import site, ModelStark from .models import * from django.forms import ModelForm class BookModelForm(ModelForm): class Meta: model = Book fields = "__all__" labels = { "title" : "书籍名称" , "publishDate" : "出版日期" , "price" : "价格" , "publish" : "出版社" , "authors" : "作者" } class BookConfig(ModelStark): list_display = [ "title" , "price" , "publishDate" ] modelform_class = BookModelForm site.register(Book, BookConfig) |
(3)显示效果:
5、添加信息提交
(1)add_view视图函数中处理post请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class ModelStark( object ): def add_view( self , request): ModelFormDemo = self .get_modelform_class() if request.method = = "POST" : form = ModelFormDemo(request.POST) if form.is_valid(): # 校验字段全部合格 form.save() return redirect( self .get_list_url()) # 跳转到当前访问表的查看页面 # (精髓)校验有错误返回页面,且包含了错误信息 return render(request, "add_view.html" , locals ()) form = ModelFormDemo() # 实例化 return render(request, "add_view.html" , locals ()) |
注意校验通过跳转到当前访问表的查看页面;校验不通过返回添加页面,且包含错误信息。
(2)add_view.html在提交报错时显示错误信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | < style > input,select { /*代码省略*/ } .error { color: red; } </ style > < body > < h3 >添加页面</ h3 > < div class="container"> < div class="row"> < div class="col-md-6 col-md-offset-3"> < form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} < div > < label for="">{{ field.label }}</ label > {{ field }} < span class="error pull-right">{{ field.errors.0 }}</ span > </ div > {% endfor %} < button type="submit" class="btn btn-default pull-right">提交</ button > </ form > </ div > </ div > </ div > </ body > |
(3)提交显示效果如下所示:
二、制作编辑页面
编辑页面视图和模板都与添加页面非常相似。
1、change_view视图编写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class ModelStark( object ): def change_view( self , request, id ): """编辑视图""" ModelFormDemo = self .get_modelform_class() # 编辑对象 edit_obj = self .model.objects. filter (pk = id ).first() if request.method = = "POST" : form = ModelFormDemo(request.POST, instance = edit_obj) # instance就是给这个记录更改为最新的数据 if form.is_valid(): # 校验字段全部合格 form.save() return redirect( self .get_list_url()) # 跳转到当前访问表的查看页面 # (精髓)校验有错误返回页面,且包含了错误信息 return render(request, "add_view.html" , locals ()) form = ModelFormDemo(instance = edit_obj) # 用instance放入编辑对象就有了编辑数据 return render(request, "change_view.html" , locals ()) |
这里最大的区别就是获取了当前的编辑对象,使用instance放入编辑对象获取编辑数据;同时在post请求中将记录更新为最新的数据。
这里是直接把add_view.html复制了一份做成了change_view.py,修改效果如下所示:
2、{% include 'form.html' %}优化代码重复
创建一个form.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | < div class="container"> < div class="row"> < div class="col-md-6 col-md-offset-3"> < form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} < div > < label for="">{{ field.label }}</ label > {{ field }} < span class="error pull-right">{{ field.errors.0 }}</ span > </ div > {% endfor %} < button type="submit" class="btn btn-default pull-right">提交</ button > </ form > </ div > </ div > </ div > |
add_view.html和change_view.html的body部分修改如下:
1 2 3 4 | < body > < h3 >编辑页面</ h3 > {% include 'form.html' %} </ body > |
三、制作删除页面
删除时不要直接删除,需要提示确认。
1 2 3 4 5 6 7 8 9 10 | class ModelStark( object ): def delete_view( self , request, id ): url = self .get_list_url() if request.method = = "POST" : self .model.objects. filter (pk = id ).delete() return redirect(url) # self.model.objects.filter(pk=id).delete() return render(request, "delete_view.html" , locals ()) |
一个form表单里面只能有一个请求按钮,因此确认删除是按钮,取消是一个a标签跳转到查看页面。
delete_view.html:
1 2 3 4 5 6 7 8 9 | < body > < h3 >删除页面</ h3 > < form action="" method="post"> {% csrf_token %} < button >确认删除?</ button > < a href="{{ url }}">取消</ a > </ form > </ body > |
执行效果:
确认后显示效果如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术