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数据库,开发新闻发布系统
本教程致力于程序员可以快速的学习安卓移动端手机开发. 适合于已经习得一种编程语言的同仁. 更多志同道合,想要学习更多编程技术的大神们. 小弟不才,麻烦关注一下我的今日头条号-做全栈攻城狮. 本文章是基 ...
随机推荐
- Ansible Ad-Hoc与常用模块
ansible 执行结果信息–各颜色说明:ansible Ad-Hoc 说明:ansible 如何查看帮助文档与常用模块详解 主机规划 添加用户账号 说明: 1. 运维人员使用的登录账号: 2. 所有 ...
- Python深度学习 deep learning with Python
内容简介 本书由Keras之父.现任Google人工智能研究员的弗朗索瓦•肖莱(François Chollet)执笔,详尽介绍了用Python和Keras进行深度学习的探索实践,涉及计算机视觉.自然 ...
- 《ASP.NET Core 3框架揭秘》5折预售暨样章发布
<ASP.NET Core 3框架揭秘>于昨天在下午京东正式开始预售,并在半天之内销售近一千套.为了回馈读者,出版社与京东谈了一个5折的价格.与此同时,我将本书最核心的内容作为样章(3章) ...
- Magento2-2.3.4 win10安装完magento无法加载静态资源导致无法进入后台登录页面
后台面无法进入,截图如下
- c# Dictionary<string, object> 转JSON字符串
JavaScriptSerializer jss = new JavaScriptSerializer(); Dictionary<string, object> dict = new D ...
- Redis 【常识与进阶】
Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久 ...
- 一夜搞懂 | JVM GC&内存分配
前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习GC&内存分配? 时代发展到现在,如今的内存动态分配与内存回收技术已经相当成 ...
- 干货 | NLP算法岗大厂面试经验与路线图分享
最近有好多小伙伴要面经(还有个要买简历的是什么鬼),然鹅真的没有整理面经呀,真的木有时间(。 ́︿ ̀。).不过话说回来,面经有多大用呢?最起码对于NLP岗位的面试来说,作者发现根本不是面经中说的样子 ...
- 第 k 小的数
一.寻找两个有序数组的中位数 1.1 问题描述 给定两个大小为 m 和 n 的不同时为空的有序数组 nums1 和 nums2.找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m ...
- 学习方法,学习方式By:ラピスラズリ(Dawn)20200407
原创,转载请注明,谢谢!