modelform+代码发布系统前奏
注意点
<form class="form-horizontal" method="post" novalidate>
method="post" : 指定form表单提交方式
novalidate : 去除前端校验
field_obj.widget.attrs['class'] = 'form-control' : 添加class='form-control'属性
<span style="color: red">{{ form_obj.hostname.errors.0 }}</span> # 渲染错误信息
# 如何区分编辑还是新增就是看有没有instance参数
form_obj = ServerModeForm(data=request.POST) # 新增
form_obj = ServerModeForm(instance=edit_obj) # 渲染标签,渲染数据
form_obj = ServerModeForm(data=request.POST,instance=edit_obj) # 编辑
<a href="{% url 'server_edit' server_obj.pk %}">编辑</a>
form.html 添加编辑页面
{% extends 'base.html' %}
{% block content %}
<form class="form-horizontal" method="post" novalidate>
{% csrf_token %}
{% for foo in form_obj %}
<div class="form-group">
<label for="{{ foo.id_for_label }}"
class="col-sm-2 control-label">{{ foo.label }}</label>
<div class="col-sm-10">
{{ foo}}
<span style="color: red">{{ foo.errors.0 }}</span>
</div>
</div>
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">提交</button>
</div>
</div>
</form>
{% endblock %}
ModelForm
from django.forms import ModelForm
from app01 import models
class ServerModeForm(ModelForm):
class Meta:
model = models.Server
fields = "__all__"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# OrderedDict([('hostname', <django.forms.fields.CharField object at 0x0000029EBC724518>)])
# print(self.fields)
# 给所有的字段加class的属性
for k, field_obj in self.fields.items():
field_obj.widget.attrs['class'] = 'form-control'
添加
html
<a href="{% url 'server_add'%}" class="btn btn-danger" style="margin: 10px 0">添加数据</a>
def server_add(request):
# 1 先生成一个modelform的空对象
form_obj = ServerModeForm() # 渲染标签
if request.method == 'POST':
form_obj = ServerModeForm(data=request.POST) # 新增
# 3 判断是否合法
if form_obj.is_valid():
# 保存数据
form_obj.save()
# 跳转到服务器的展示页
# return redirect('/server/list')
return redirect('server_list') # 还可以写别名 但是如果出现有名无名分组的反响解析 则必须使用reverse方法
# 2 将该对象传给html
return render(request, 'form.html', locals())
编辑
html
{% for server_obj in server_queryset %}
<tr>
<td>{{ server_obj.pk }}</td>
<td>{{ server_obj.hostname }}</td>
<td>
<a href="{% url 'server_edit' server_obj.pk %}">编辑</a>
<a href="" onclick="removeDate(this,{{ server_obj.pk }})" >删除</a>
</td>
</tr>
{% endfor %}
py
def server_edit(request, edit_id):
edit_obj = models.Server.objects.filter(pk=edit_id).first()
# 生成待编辑的modeform对象
form_obj = ServerModeForm(instance=edit_obj) # 渲染标签,渲染数据
if request.method == 'POST':
form_obj = ServerModeForm(data=request.POST, instance=edit_obj) # 编辑
if form_obj.is_valid():
form_obj.save()
return redirect('server_list')
return render(request, 'form.html', locals())
删除
html
{% for server_obj in server_queryset %}
<tr>
<td>{{ server_obj.pk }}</td>
<td>{{ server_obj.hostname }}</td>
<td>
<a href="{% url 'server_edit' server_obj.pk %}">编辑</a>
<a href="" onclick="removeDate(this,{{ server_obj.pk }})" >删除</a>
</td>
</tr>
{% endfor %}
# 删除Js
function removeDate(ths,sid) {
var res = confirm('确定删除吗?');
if (res){
$.ajax({
url:'/server/delete/'+sid+'/',
type:'get',
success:function (args) {
if (args.status){
$(ths).parent.parent.remove() # DOM操作,删除标签
}
}
})
}
}
py
def server_delete(request, delete_id):
models.Server.objects.filter(pk=delete_id).delete()
return JsonResponse({'status': True}) # 返回给前端,表示已经删除
代码优化
优化1
将所有的modelform单独抽取出来
将modelform类中所有公共的部分抽取出来形成基类
# 父类
from django.forms import ModelForm
class BaseModelForm(ModelForm):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
# print(self.fields) # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x10c99c198>)])
# 给所有的字段加class属性
for k,field_obj in self.fields.items():
field_obj.widget.attrs['class'] = 'form-control'
# 子类
from app01.myforms.base import BaseModelForm
from app01 import models
class ServerModelForm(BaseModelForm):
class Meta:
model = models.Server
fields = "__all__"
优化2
当模型表字段特别多的时候,并且并不是所有的字段都需要展示到前端给用户观看
from django.forms import ModelForm
class BaseModelForm(ModelForm):
# 自定义字段是否需要加额外属性的配置
exclude_bootstrap = []
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
# print(self.fields) # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x10c99c198>)])
# 给所有的字段加class属性
for k,field_obj in self.fields.items():
if k in self.exclude_bootstrap:
continue # 排除在外不添加样式
field_obj.widget.attrs['class'] = 'form-control'
优化3
项目表需要额外添加字段
# 线上服务器地址
path = models.CharField(verbose_name='线上地址',max_length=64)
# 关联服务器
"""
一个项目可以跑在多个服务器上
一个服务器其实也可以跑多个项目 (公司服务器不够的时候 可以混用)
"""
servers = models.ManyToManyField(to='Server',verbose_name='关联服务器')
# 项目展示页面额外展示当前两个字段
<th>线上地址</th>
<th>线上关联服务器</th>
<td>{{ project_obj.path }}</td>
<td>
{% for server_obj in project_obj.server.all %}
<span style="border: 1px solid black;padding: 5px">{{ server_obj.hostname }}</span>
{% endfor %}
</td>
modelform+代码发布系统前奏的更多相关文章
- 【运维工具】Git代码发布系统
引言 代码发布系统是互联网公司必备的运维系统,作用主要用户发布业务代码 到 业务服务器 为什么需要代码发布系统 有的同学可能说,我们公司服务器就那么一台,做个发布系统太麻烦了? 不认同这说法 发布系统 ...
- Walle代码发布系统
Walle 一个web部署系统工具,配置简单.功能完善.界面流畅.开箱即用!支持git.svn版本管理,支持各种web代码发布,PHP,Python,JAVA等代码的发布.回滚,可以通过web来一键完 ...
- svn 结合rsync 的代码发布系统
由开发提交到测试环境,经测试,在由运维统一上线.试验需求一台测试服务器,一台线上(生产环境)服务器.测试服务器上跑svn是开发用于代码管理,而线上跑的svn是运维用来代码上线的.结合rsync保持测试 ...
- walle代码发布系统配置
walle Walle 一个web部署系统工具,配置简单.功能完善.界面流畅.开箱即用! 支持git.svn版本管理,支持各种web代码发布, PHP,Python,JAVA等代码的发布.回滚,可以通 ...
- 【手把手】JavaWeb 入门级项目实战 -- 文章发布系统 (第十二节)
好的,那么在上一节中呢,评论功能的后台已经写好了,这一节,先把这部分后台代码和前台对接一下. 1.评论功能实现 我们修改一下保存评论按钮的点击事件,用jQuery的方式获取文本框中的值,然后通过aja ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(35)-文章发布系统②-构建项目
系列目录 注:阅读本文,需要阅读本系列的之前文章 代码生成器下载地址(文章开头处) 接下来我们建立数据库的表和各层的代码 我们只需要两张表,文章列表(MIS_Article)和类别表(MIS_Arti ...
- 【NodeJS 学习笔记04】新闻发布系统
前言 昨天,我们跟着这位大哥的博客(https://github.com/nswbmw/N-blog/wiki/_pages)进行了nodeJS初步的学习,最后也能将数据插入数据库了 但是一味的跟着别 ...
- 完成一个MVC+Nhibernate+Jquery-EasyUI信息发布系统
一.最近学习了Jquery-EasyUI框架,结合之前用过的MVC3+Nhibernate做一个信息发布系统,对工作一年半的自己做一个总结吧!(也正好 供初学者学习!) 二.先上截图(系统简介),让大 ...
- 安卓项目-利用Sqlite数据库,开发新闻发布系统
本教程致力于程序员可以快速的学习安卓移动端手机开发. 适合于已经习得一种编程语言的同仁. 更多志同道合,想要学习更多编程技术的大神们. 小弟不才,麻烦关注一下我的今日头条号-做全栈攻城狮. 本文章是基 ...
随机推荐
- 强大的Flutter App升级功能
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 应用程序升级功能是App的基础功能之一,如果没有此功能会造 ...
- 测试必知必会系列- Linux常用命令 - mv
21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 移动当 ...
- HTTP 与 HTTPS 的区别以及 HTTPS 建立连接的过程
HTTP 与 HTTPS 区别 HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好. 使用 HTTPS 协议需要到 CA(Certifi ...
- Servlet(简介,请求参数,页面跳转,生命周期,创建,配置,ServletContext,线程)
1.Servlet简介 servlet是java servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序, 主要功能在于交互式浏览和修改数据,生成动态的web内容 服务端运行的 ...
- JWT签发token
目录 一. 认证的发展历程简介 二. JWT签发Token源码分析 2.1 JWT工作原理及简介 2.2 JWT生成token源码分析 返回目录 一. 认证的发展历程简介 这里真的很简单的提一下认证的 ...
- 洛谷3388 tarjan割点
题目链接:https://www.luogu.com.cn/problem/P3388 tarjan算法果然牛逼,时间复杂度是O(|V|+|E|),所以1e4个结点2e5条边的图完全不在话下orz o ...
- R之Shiny学习笔记
官方教程:https://shiny.rstudio.com/tutorial/ 中文教程:http://yanping.me/shiny-tutorial/ 英文教程:https://deanatt ...
- xmake v2.3.2 发布, 带来和ninja一样快的构建速度
这个版本重点重构优化了下内部并行构建机制,实现多个target间源文件的并行编译,以及并行link的支持,同时优化了xmake的一些内部损耗,修复影响编译速度的一些bug. 通过测试对比,目前的整体构 ...
- win10 Redis闪退问题
问题:双击redis-server.exe,闪退 解决办法:win+R,输入cmd进入命令行模式,接着cd进入Redis安装根目录,再输入:redis-server.exe redis.windows ...
- OSLab:开启保护模式
日期:2019/5/22 关键词:操作系统:OS:保护模式:A20地址线激活:分页开启:二级页表的设置 PS:OSLAB实验课的整理. 本文主要内容是分析操作系统中一个简易的MBR. 建议先阅读:ht ...