扩展知识点:当服务器特别多的时候从平台下载数据,如何减轻平台的压力
最新的技术点是p2p技术也叫比特流技术
所有人都可以成为数据的下载者以及上传者
为什么有时候下载电影速度快,有时候慢,快的时候可能是因为你的室友电脑里面就有该资源,你就是从你室友的电脑中下载的,慢的时候则是因为你的周边都没有该资源的提供者
主要是用modelform实现服务器及项目的增删改查操作
任何一个项目毫不夸张的说80%以上都是由增删改查组成的,其次带你见证一下什么叫真正的搬砖
我们不直接创建所有的表,而是写一个创建一个
为了解耦合以及项目逻辑更加清晰
将全局的templates文件夹剔除,在应用内创建自己的templates文件夹,并且将应用里面的views.py删除
创建views文件夹,里面根据功能的不用创建不同的py文件
数据校验
前端字段标签渲染
展示错误信息
forms组件 >>> modelform组件
return redirect('server_list')
# redirect括号内可以直接写url 其实也可以写反向解析的别名 但是如果带有名无名分组的情况 则必须使用reverse
django默认的语言环境是英文,但是它的内部提供很多国家的语言环境,你可以修改
# 配置文件中修改参数
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
"""django内部能够支持的语言环境 可以查看它的全局配置文件"""
from django.conf import global_settings
LANGUAGE_CODE = 'en-us'
# Languages we provide translations for, out of the box.
LANGUAGES = [
('af', gettext_noop('Afrikaans')),
('ar', gettext_noop('Arabic')),
('ast', gettext_noop('Asturian')),
...
]
modelform编辑功能非常简单,只需要你给一个instance参数即可
def server_edit(request,edit_id):
# 获取编辑对象 展示到页面给用户看 之后用户再编辑 提交
edit_obj = models.Server.objects.filter(pk=edit_id).first()
"""
其实编辑页面和添加页面是一样的 不同的在于是否需要渲染默认数据
所以我们直接使用用一个页面
"""
form_obj = ServerModelForm(instance=edit_obj)
if request.method == 'POST':
form_obj = ServerModelForm(data=request.POST,instance=edit_obj)
if form_obj.is_valid():
form_obj.save() # 编辑
# 新增和编辑都是save方法 区分就依据与instance参数
return redirect('server_list')
return render(request,'form.html',locals())
删除功能需要做二次确认
并且删除完成后需要让用户能够直观的在浏览器上看到数据被删除了
不能直接刷新页面,因为如果是分页的情况,刷新页面之后肯定是在第一页
如果我是在第99页删除了1条数据,数据删除并且还在99页
<script>
function removeData(ths,delete_id) {
var res = confirm('是否确定删除?');
// 返回值 判断用户点击的确定还是取消
if(res){
// 朝后端发送删除数据的请求
$.ajax({
url:'/server/delete/' + delete_id + '/',
type:'get',
dataType:'JSON',
success:function (args) {
if(args.status){
// 通过DOM操作 来删除页面数据
$(ths).parent().parent().remove()
}
}
})
}
}
</script>
class Project(models.Model):
"""项目表"""
# luffycity cmdb crm ...
title = models.CharField(verbose_name='项目名',max_length=32)
# https://www.github.com/xxx.git/
repo = models.CharField(verbose_name='仓库地址',max_length=32)
env_choices = (
('prod','正式'),
('test','测试'),
)
env = models.CharField(verbose_name='环境',max_length=16,choices=env_choices,default='test')
针对项目表的增删改查直接拷贝服务器表的代码修改即可
不要上来就做优化,一定是用简单最lowb的方式将代码写好之后,再考虑优化的问题
视图函数与modelform应该区分开
"""
app01
-myforms
--project.py
--server.py
"""
整合服务器modelform和项目modelform类相同的代码 抽成基类
"""
什么是类
类是对象公共的属性与技能的结合体
什么是基类
基类是类公共的属性与技能的结合体
"""
from django.forms import ModelForm
# 父类
class BaseModelForm(ModelForm):
# 将是否添加样式 做成可配置的
exclude_bootstrap = []
# 重写init方法 当你不知道一个方法是否有参数或者有几个参数的时候 建议你写*args,**kwargs
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 额外的操作
# print(self.fields) # 有序字典 OrderedDict([('hostname', <django.forms.fields.CharField object at 0x1092abf60>)])
# 给所有的字段添加样式form-control
for k, field in self.fields.items():
# 判断当前字段是否需要加
if k in self.exclude_bootstrap:
# 直接跳过
continue
field.widget.attrs['class'] = 'form-control'
# 子类
from app01 import models
from app01.myforms.base import BaseModelForm
class ProjectModelForm(BaseModelForm):
class Meta:
model = models.Project
fields = "__all__"
项目表需要再添加几个字段
# /data/temp/...
path = models.CharField(verbose_name='线上项目地址',max_length=32)
# 项目跑在服务器上 那么项目和服务器应该是有关系的
"""
一个项目可以是否可以跑在多台服务器上 可以!
一台服务器上是否可以跑多个项目呢 当资金不是很充足的时候 服务器是可以混用的 可以!
"""
servers = models.ManyToManyField(verbose_name='关联服务器',to='Server')
class DeployTask(models.Model):
"""发布任务单
项目主键 项目版本
1 v1
1 v2
1 v3
2 v1
"""
# luffycity-test-v1-20201111111
"""项目名-环境-版本-日期"""
uid = models.CharField(verbose_name='标识',max_length=32)
# 任务与项目是一对多的关系 并且任务是多 项目是一
# django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常:
# TypeError: init() missing 1 required positional argument: ‘on_delete’
project = models.ForeignKey(verbose_name='项目',to='Project',on_delete=models.CASCADE)
tag = models.CharField(verbose_name='版本',max_length=32)
status_choices = (
(1,'待发布'),
(2,'发布中'),
(3,'成功'),
(4,'失败'),
)
status = models.IntegerField(verbose_name='状态',choices=status_choices,default=1)
"""预留了一些钩子功能"""
before_download_script = models.TextField(verbose_name='下载前脚本', null=True, blank=True)
after_download_script = models.TextField(verbose_name='下载后脚本', null=True, blank=True)
before_deploy_script = models.TextField(verbose_name='发布前脚本', null=True, blank=True)
after_deploy_script = models.TextField(verbose_name='发布后脚本', null=True, blank=True)
TypeError: init() missing 1 required positional argument: ‘on_delete’
当执行 python manage.py makemigrations 出现错误:TypeError: init() missing 1 required positional argument: ‘on_delete’
解决方案:
定义外键的时候需要加上 on_delete=;
即:contract = models.ForeignKey(Contract, on_delete=models.CASCADE)
原因如下:
django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常:
TypeError: init() missing 1 required positional argument: ‘on_delete’
on_delete各个参数的含义如下:
on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET, # 删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
由于多对多(ManyToManyField)没有 on_delete 参数,所以以上只针对外键(ForeignKey)和一对一(OneToOneField)
关于Django的models字段详细信息:https://www.cnblogs.com/Darksugar/p/7426490.html
原文:https://www.cnblogs.com/zhangchaocoming/p/12521677.html