经典的生活价值观
别让人生,输给了心情。心情不是人生的全部,却能左右人生的全部。心情好,什么都好,心情不好,一切都乱了。我们常常不是输给了别人,而是坏心情贬低了我们的形象,降低了我们的能力,扰乱了我们的思维,从而输给了自己。
控制好心情,生活才会处处祥和。好的心态塑造好心情,好心情塑造最出色的你。
静静的过自己的生活,心若不动,风又奈何。你若不伤,岁月无恙。
BBS 项目开发逻辑梳理
第一步:先进行数据库设计
数据库设计规则是:
1.先创建基表:用户表、站点表、文章表、标签表、分类表、文章2标签第三张关系表、点赞点踩表、评论表
2.书写表中的基本含有的字段
3.添加外键(一对一,一对多,多对多)
4.第三张关系表
注意事项:创建外键关系的时候,to='表名',不要忘记引号,null=true,并不是所有的外键都加的
第二步settings配置
一定要进行settings的相关配置:
1.数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bbszikao',
'USER':'root',
'PASSWORD': 'root',
'HOST':'127.0.0.1',
'PORT':3306,
'CHARSET':'utf8'
}
}
2.静态文件资源配置
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static')
]
3.models.py文件中,用户表继承AbstractUser类,需要对其进行settings配置
from django.contrib.auth.models import AbstractUser
配置auth模块的访问:
AUTH_USER_MODEL='app01.Userinfo'
4.静态图片资源settings配置+urls路由访问配置,暴露给用户查看,用户注册可以访问到默认头像
#settings文件配置:
MEDIA_ROOT=os.path.join(BASE_DIR,'media')
#urls文件访问头像路由配置
url(r'^media/(?P.*)', serve, {'document_root': settings.MEDIA_ROOT}),
第三步功能开发
注册功能
后端开发逻辑:
分为:register函数+register.html+myform.py文件
后端开发逻辑:
# myform.py 文件
1.建立myform.py文件,利用forms表单,提交注册的数据信息
创建class MyRegForm(forms.Form):类
用户名,密码,确认密码,邮箱
from django import forms
from app01 import models
class MyRegForm(forms.Form):
username = forms.CharField(max_length=8,min_length=3,label='用户名',
error_messages={
'max_length': '用户名最长8位',
'min_length': '用户名最短3位',
'required': "用户名不能为空"
},
#标签设置
widget=forms.widgets.TextInput(attrs={'class': 'form-control'})
建立局部钩子函数校验用户名是否存在
# 局部钩子 校验用户名是否已存在
def clean_username(self):
username = self.cleaned_data.get('username')
res = models.Userinfo.objects.filter(username=username)
if res:
self.add_error('username','用户名已存在')
return username
建立全局钩子函数校验密码是否一致
# 全局钩子 校验两次密码是否一致
def clean(self):
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if not password == confirm_password:
self.add_error('confirm_password','两次密码不一致')
return self.cleaned_data
# models.py 文件
2.把myform文件中的MyRegForm表单对象拿到,
然后把form_obj对象发送给前端register.html页面
form_obj=myform.MyRegForm()
return render(request,'register.html',locals())
后端开发逻辑如下:
把myform文件中的MyRegForm表单对象拿到
判断前端发送过来的请求方式是不是post请求
定义back_dic 字典
对用户在前端提交的post数据进行校验,生成form_obj对象
如果数据合法:
获取所有键值对
pop掉确认密码键值对
获取前端发送的文件请求(avatar),创建文件对象
判断用户是否上传文件:
上传文件了,把avatar添加到clean_data字典对象中
用户表创建用户(create_user)
back_dic字典添加msg信息,注册成功
back_dic字典添加url,login路径
数据不合法:
字典添加code=2000
字典添加msg=form_obj.errors
返回json数据到前端,[需要导入JsonResponse模块(from django.http import JsonResponse)]
然后把form_obj对象发送给前端register.html页面
前端开发逻辑:
上传头像文件功能,注册按钮功能
前端开发逻辑:register.html文件,前端只整理需要整理的
上传头像文件功能
//上传头像文件相关的处理
$('#mdd').on('change',function () {
//利用内置对象filereader完成文件的读取操作
let MyFileReader=new FileReader();
//获取用户上传的文件对象
let fileobj=$(this)[0].files[0];
//让文件阅读器读取文件,IO操作,异步
MyFileReader.readAsDataURL(fileobj);
//将读取之后的内容替换到img标签src属性中
MyFileReader.οnlοad=function () {
$('#img').attr('src',MyFileReader.result)
}
});
// 注册按钮
$('#submit').click(function () {
// 将用户输入的数据全部发送给后端 普通的键值对 文件
let MyFormData = new FormData();
// 不停的朝里面添加键值对
{#MyFormData.append('','')#}
{#console.log($('#myform').serializeArray())#}
// 普通键值对添加完毕 (利用form标签内部有一个自动序列化普通键值对方法)
$.each($('#myform').serializeArray(),function (index,obj) {
MyFormData.append(obj.name,obj.value)
});
// 手动添加文件数据
MyFormData.append('avatar',$('#mdd')[0].files[0]);
// 发送ajax请求
$.ajax({
url:'',
type:'post',
data:MyFormData,
// 发送文件一定要指定两个参数
processData:false, // 不要让浏览器处理你的数据
contentType:false, // 不要使用任何的编码 django能够识别对象自身
success:function (data) {
if (data.code == 1000){
// 跳转到登录页面
window.location.href = data.url
}else{
$.each(data.msg,function (index,obj) {
{#console.log(index,obj)#} // index就是报错字段 obj就是错误信息 数组的形式
// 获取报错字段 手动拼接出该字段所对应的input框的id值
let targetId = '#id_' + index;
$(targetId).next().text(obj[0]).parent().addClass('has-error')
})
}
}
})
});
// input框获取焦点事件,---这个是鼠标放到input框上面后,错误信息消失
$('input').focus(function () {
$(this).next().text('').parent().removeClass('has-error')
})
图片验证码功能
后端开发逻辑
1.所需要的模块
import random
from PIL import Image,ImageDraw,ImageFont
from io import BytesIO,StringIO
'''
内存管理器模块:
BytesIO 保存数据,并且在获取的时候,是以二进制的方式给你
StringIO 保存数据,并且在获取的时候,是以字符串的方式给你
Image 生成图片
ImageDraw 在图片上写字
ImageFont 控制字的字体样式
'''
#io_obj=BytesIO() #你就将该对象看成是文件句柄即可
'''
什么是文件句柄???
在文件I/O中,要从一个文件读取数据,应用程序首先
要调用操作系统函数并传送文件名,并选一个到该文件
的路径来打开文件。该函数取回一个顺序号,即文件句柄
(file handle),该文件句柄对于打开的文件是唯一的
识别依据。要从文件中读取一块数据,应用程序需要调用
函数ReadFile,并将文件句柄在内存中的地址和要拷贝的
字节数传送给操作系统。当完成任务后,再通过调用系统函数
来关闭该文件。”
'''
2.图片验证码的开发分为两步:
随机取色+图片验证码
2.1随机取色
def get_random():
return random.randint(0,255),random.randint(0,255),random.randint(0,255)
2.2图片验证码函数
图片的宽高和随机取色---生成画板对象 Image.new
将生成好的图片对象交给ImageDraw---画笔对象 ImageDraw.Draw
字体样式---何种字体 ImageFont.truetype
#随机验证码---何种要求(大小写英文加数字,5位)
定义code=''
循环5次:
大写字母upper_str
小写字母lower_str
str(随机数) random_int
<