代码拉取完成,页面将自动刷新
开发进程
学习forms.ModelForm
使用CDN制作前端
Redis跟Mysql数据库设置
redis
CACHES = {
"default": {
"BACKED": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {
"max_connections": 1000,
"encoding": "utf-8"
},
}
}
}
views中的使用
from django_redis import get_redis_connection
def get_data(request):
conn = get_redis_connection('default')
conn.set('key', 'value', ex=19)
前端的html的使用
// 获取当前form表单中所有的input选项的输入内容
$('#id').serialize()
Form
通过form更改表单的显示,包括id等数据
可以通过fields等确定输入的列表
部分样式应用BootStrap, 定制ModelForm插件
class BootStrapForm(object):
bootstrap_class_exclude = []
def __init__(self, *args, **kwargs):
"""重写init方法,让每个字段都加上同样的属性, 增加显示样例"""
super().__init__(*args, **kwargs)
for name, fields in self.fields.items():
# fields: 字段对象
if name in self.bootstrap_class_exclude:
continue
fields.widget.attrs['class'] = 'form-control' # 给每个字段增加class属性
fields.widget.attrs['placeholder'] = '请输入{}'.format(fields.label, )
class ProjectModelsForm(BootStrapForm, forms.ModelForm):
bootstrap_class_exclude = ['color']
class Meta:
model = models.Project
fields = ['name', 'color', 'desc']
widgets = {
'desc': forms.Textarea,
'color': ColorRadioSelect(attrs={'class': 'color-radio'}),
}
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request
from django.forms import RadioSelect
class ColorRadioSelect(RadioSelect):
template_name = 'widgets/color_radio/radio.html' #自定义的文件,可以更改部分的标签
option_template_name = 'widgets/color_radio/radio_option.html'
在form=ModelForm(instance=new_object) 更新对应的数据库,而不是创建
URL
markdown编辑器的使用
下载markdown的插件
https://gitee.com/pandao/editor.md/repository/archive/master.zip
下载之后放在静态文件中并加载后导入css和js
js中引入对应的id
$(function () {
initCatalog();
initEditorMd();
});
/* 初始化markdown编辑器*/
function initEditorMd() {
editormd('editor', {
placeholder: '请输入内容',
height: 500,
path: "{% static 'plugin/editor-md/lib/' %}", //指定静态lib中依赖文件
})
}
全屏问题
需要设置对应div全屏状态下最上端显示
.editor-fullscreen{ // 可以通过-fullscreen定义全屏状态
z-index: 1001;
}
markdown预览模式
<link rel="stylesheet" href="{% static 'plugin/editor-md/css/editormd.preview.min.css' %}">
<div id="previewMarkdown">
<textarea>
{{ wiki_object.content }}
</textarea>
</div>
<script src="{% static 'plugin/editor-md/editormd.min.js' %}"></script>
<script src="{% static 'plugin/editor-md/lib/marked.min.js' %}"></script>
<script src="{% static 'plugin/editor-md/lib/prettify.min.js' %}"></script>
<script src="{% static 'plugin/editor-md/lib/raphael.min.js' %}"></script>
<script src="{% static 'plugin/editor-md/lib/sequence-diagram.min.js' %}"></script>
<script src="{% static 'plugin/editor-md/lib/flowchart.min.js' %}"></script>
<script src="{% static 'plugin/editor-md/lib/jquery.flowchart.min.js' %}"></script>
function initPreviewMarkdown() {
editormd.markdownToHTML("previewMarkdown", {
htmlDecode: "style,script,iframe", // 屏蔽前端输入html代码
})
}
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
SMS_SDK = 1400399389
SMS_APP_KEY = "e9f4f9390bb03387c58ca5a7bc82bdc7"
SMS_SIGNAL = "开发之路tcc"
SMS_TEL = '13420129486' # 电话
SMS_SIGN = 298799 # sms的签名id
SMS_ID = 661589 # sms的模板id
CACHES = { # redis的配置
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {
"max_connections": 1000,
"encoding": "utf-8"
},
}
}
}
COS_ID = "AKIDdhqjU3bvFI6vUoqCwQSFl0A6JK6e3frs"
COS_KEY = "LYYDhsnt2vLVNyvc3i8RSDk6Bze8ON5f"
前端使用临时凭证去上传数据
创建桶
创建桶时需要注意跨域的问题
def create_bucker(bucket, region='ap-chengdu'):
"""
创建桶
:param bucket:
:param region:
:return:
"""
# region = 'ap-shenzhen-fsi'
config = CosConfig(Region=region, SecretId=settings.COS_ID, SecretKey=settings.COS_KEY)
client = CosS3Client(config)
client.create_bucket(
Bucket=bucket,
ACL='public-read'
)
# 解决上传文件跨域问题
"""
cors_config = {
'CORSRule': [
{
'ID': '1234',
'AllowedOrigin': ['http://www.qq.com'],
'AllowedMethod': ['GET', 'PUT'],
'AllowedHeader': ['x-cos-meta-test'],
'ExposeHeader': ['x-cos-meta-test1'],
'MaxAgeSeconds': 500
}
]
}
response = client.put_bucket_cors(
Bucket='bucket',
CORSConfiguration=cors_config
)"""
cors_config = {
'CORSRule': [
{
'AllowedOrigin': '*',
'AllowedMethod': ['GET', 'PUT', 'HEAD', 'POST', 'DELETE'],
'AllowedHeader': '*',
'ExposeHeader': '*',
'MaxAgeSeconds': 500
}
]
}
client.put_bucket_cors(
Bucket=bucket,
CORSConfiguration=cors_config
)
使用sts创建临时凭证
def credential(bucket, region):
"""获取临时凭证"""
from sts.sts import Sts
config = {
# 临时凭证的有效时长,单位:秒
'duration_seconds': 180,
# 固定密钥_id
'secret_id': settings.COS_ID,
'secret_key': settings.COS_KEY,
# bucket
'bucket': bucket,
# region
'region': region,
# 根据用户登录的路径判断上传的类型, *为所有类型
'allow_prefix': '*',
# 设置密钥能使用的权限
'allow_actions': [
# // 简单上传操作
# "name/cos:PutObject",
# // 表单上传对象
# "name/cos:PostObject",
# // 分块上传:初始化分块操作
# "name/cos:InitiateMultipartUpload",
# // 分块上传:List
# 进行中的分块上传
# "name/cos:ListMultipartUploads",
# // 分块上传:List
# 已上传分块操作
# "name/cos:ListParts",
# // 分块上传:上传分块块操作
# "name/cos:UploadPart",
# // 分块上传:完成所有分块上传操作
# "name/cos:CompleteMultipartUpload",
# // 取消分块上传操作
# "name/cos:AbortMultipartUpload"
'*',
],
}
sts = Sts(config)
result_dict = sts.get_credential()
return result_dict
# 之后返回对应的dict
前端创建对应cos
var COS_OBJECT = new COS({
// 必选参数
getAuthorization: function (options, callback) {
// 访问后端获取临时凭证
$.get(COS_REDENTIAL, {
// 可从 options 取需要的参数
}, function (data) {
var credentials = data && data.credentials;
if (!data || !credentials) return console.error('credentials invalid');
callback({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
XCosSecurityToken: credentials.sessionToken,
// 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000900
});
});
}
});
function bindUploadFile() {
// 获取临时凭证, 根据凭证上传
$('#uploadFile').change(function () {
var fileList = $(this)[0].files; // 获取文件上传
$.each(fileList, function (index, fileObject) {
// 循环遍历每个文件,并上传
var fileName = fileObject.name;
console.log(fileName)
// 异步上传文
COS_OBJECT.putObject({
Bucket: "{{ request.tracer.project.bucket }}",
Region: "{{ request.tracer.project.region }}",
Key: fileName,
Body: fileObject, // 上传文件对象
onProgress: function (progressData) {
console.log('文件上传进度--->', fileName, JSON.stringify(progressData));
}
}, function (err, data) {
console.log(err || data);
})
})
})
}
var fileName = fileObject.name;
console.log(fileName)
// 异步上传文
COS_OBJECT.putObject({
Bucket: "{{ request.tracer.project.bucket }}",
Region: "{{ request.tracer.project.region }}",
Key: fileName,
Body: fileObject, // 上传文件对象
onProgress: function (progressData) {
console.log('文件上传进度--->', fileName, JSON.stringify(progressData));
}
}, function (err, data) {
console.log(err || data);
})
var COS_OBJECT = new COS({
// 必选参数
getAuthorization: function (options, callback) {
// 访问后端获取临时凭证
$.get(COS_REDENTIAL, {
// 可从 options 取需要的参数
}, function (data) {
var credentials = data && data.credentials;
if (!data || !credentials) return console.error('credentials invalid');
callback({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
XCosSecurityToken: credentials.sessionToken,
// 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000900
});
});
}
});
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。