1206 BBS注册
昨日内容
昨日内容
基于django中间件实现功能的插拔式设计
1.设计思想
2.自己记下来
跨站请求伪造csrf
1.出处
2.如何实施
django里面校验csrf是由中间件执行的csrf...
提交post请求如何通过csrf校验
form表单
只需要在form表单内写一句话
{% csrf_token %}
ajax
方式1
自己在data参数里面加上键值对
data:{'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()}
方式2
利用模板语法
data:{'csrfmiddlewaretoken':'{{ csrf_token }}' }
# 前端参数如果没有起作用 你可以尝试着给参数加一个引号
方式3
利用官方提供的js代码
拷贝代码放入一个js文件中 你字需要在html页面上导入该js文件
之后你就不需要手动操作任何csrf相关的代码
# 拷贝到你们的本地
相关的装饰器
csrf_protect
csrf_exempt
# FBV中跟普通的装饰器一模一样
# CBV中csrf_exempt这个装饰器只能给dispatch方法装 csrf_protect还是正常的跟普通的装饰器一样
开发者笔记
xxx公司
问题 解决
同在一个屋檐下
为何差距那么大
上课都是认真听讲
每晚九点半之后
周末时间
看视频是最low的复习方式
auth模块
基于auth_user表 类似于一张已经提前创建好的用户表
from django.contrib import auth
from django.contrib.auth.models import User
1.创建用户
# create() 密码存的是明文的
create_user()
craete_superuser()
2.如何判断用户名和密码是否正确
user_obj = auth.authenticate(username=jason,password=123)
3.如何保存用户登录状态
auth.login(request,user_obj) # 只要执行了这句话 在任意位置都可以通过request.user获取到当前登录的用户对象
# 自动帮你操作session表
4.如何判断当前用户是否登录
request.user.is_authenticated()
5.校验密码是否正确
request.user.check_password(old_password)
6.修改密码
request.user.set_password(new_password)
request.user.save() # 一定要执行
7.注销
auth.logout(request)
8.校验登录装饰器
# 局部的
login_required(login_url='/login/')
# 全局的
LOGIN_URL = '/login/'
login_required
# 如果都配置了 按照局部的为准
如何扩展auth_user表
方式1 利用表与表之间的一对一的关系
方式2 利用面向对象的继承
1.在models中写一个模型类继承AbstractUser
from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser):
phone = ...
avatar = ...
# 不要与原先的表中的字段冲突
2.一定要去配置文件中 指定你自己的表作为auth模块的基表
AUTH_USER_MODEL = 'app01.Userinfo'
django settings源码及实际应用
1.逻辑思路是什么
2.反射(******) + importlib模块
一切皆对象
def func():
pass
func.name = 'jason'
print(func.name)
BBS项目
1.项目开发流程
需求分析
架构师 开发组组长 草拟一些项目的大致技术点和流程
架构师 + 产品经理 + 开发组组长去客户公司听客户需求
在跟客户聊的时候 你要有意识有目的引导客户朝着你之前已经想好的
功能思路上去提需求
架构设计
架构师(框架 语言 数据库 缓存数据库 表设计 拆分功能 项目的报价(参与开发人员的个数 一个人1000~2000))
分组开发
开会(架构师组长会议) 分任务 按模块功能分的
开会(小组会议) 组长在拆分功能 每个组员写几个小功能
小组成员写代码
自己需要提前测试一下有没有bug
交付测试
妹纸多 见效最块的
一些不是显而易见的bug
如果是显而易见的bug 就需要扣你绩效
运维上线
1.委托给你们公司帮忙上线帮忙维护
2.交给对方公司
15K
基本工资 8000 6000
绩效 3000
岗位津贴 2000
其他补贴 2000
基本工资 12000
绩效 3000
2.表设计
先确定表名
再确定表字段
然后是表关系
用户表
- 利用auth_user表
- 手机号
- 头像
- 注册时间
- blog 一对一个人站点表
个人站点表
- 站点名称
- 站点标题
- 站点样式
文章标签表
- 标签名
- blog 一对多 个人站点表
文章分类表
- 分类名
- blog 一对多 个人站点表
文章表
文章标题
文章简介
文章内容
文章发布时间
blog 一对多个人站点表
tags 多对多文章标签表
category 一对多文章分类表
数据库优化设计方案
当有些数据需要要跨表查询得到时,可以直接定义成普通字段,通过代码同步更新,进行获取减少数据库压力. 文章的点赞数 点踩数 评论数
up_num down_num comment_num
在文章表中新添加三个普通字段跟对应的表中的数据同步更新即可
up_num 文章的点赞数
down_num 点踩数
comment_num 评论数
文章的点赞点踩表
- user_id 一对多用户表
- article_id 一对多文章表
- is_up booleanfield
文章的评论表
user_id 一对多用户表
article_id 一对多文章表
评论content TextField()
评论时间create_time
自关联
parent 跟自己所在的表外键关联

项目
mysql数据库的使用
创建数据库表
更改Settings中的数据库设置
__init__的设置
models表类的创建
使用django的自带表数据
from django.contrib.auth.models import AbstractBaseUser
多对多方式的建立,需要手动创建第三张表,并且外键字段through参数,在settings中配置指定使用自定义的数据表
新建static文件夹存放静态文件
settings设置 STATICFILES_DIRS
- settings
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bbs',
'USER': 'root',
'PASSWORD':'',
'HOST':'127.0.0.1',
'PORT': 3306,
'CHARSET': 'utf8'
}
}
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
# 设置指定使用django的默认表类
AUTH_USER_MODEL = 'app01.Userinfo'
- urls
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 注册功能
url(r'^register/',views.register)
]
- models
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
# 用户信息表
class Userinfo(AbstractUser):
phone = models.BigIntegerField(null=True)
# 该字段直接传文件即可,会自动将文件保存到avatar文件夹内,数据库里面存文件路径
# 如果没有传文件则会使用img文件夹下默认头像
avatar = models.FileField(upload_to='avatar/',default='static/img/default.jpg')
register_time = models.DateField(auto_now_add=True,null=True)
# 外键字段
blog = models.OneToOneField(to='Blog',null=True)
# 定义个人站点表
class Blog(models.Model):
site_name = models.CharField(max_length=32)
site_title = models.CharField(max_length=64)
# 该字段存放的是用户自己写的css文件路径
site_theme = models.CharField(max_length=64)
# 分类表
class Category(models.Model):
name = models.CharField(max_length=32)
blog = models.ForeignKey(to='Blog',null=True)
# 标签
class Tag(models.Model):
name = models.CharField(max_length=32)
blog = models.ForeignKey(to='Blog',null=True)
# 文章
class Article(models.Model):
title = models.CharField(max_length=64)
# 文章简介
desc = models.CharField(max_length=255)
# 文章内容
content = models.TextField()
create_time = models.DateField(auto_now_add=True)
# 数据库优化字段
up_num = models.IntegerField(default=0)
down_num = models.IntegerField(default=0)
comment_num = models.IntegerField(default=0)
# 外键字段
category = models.ForeignKey(to='Category',null=True)
blog = models.ForeignKey(to='Blog',null=True)
tags = models.ManyToManyField(to='Tag',through='Article2Tag',through_fields=('article','tags'))
# 文章和标签的第三张表
class Article2Tag(models.Model):
article = models.ForeignKey(to='Article')
tags = models.ForeignKey(to='Tag')
# 点赞与点踩
class UpAndDown(models.Model):
user = models.ForeignKey(to='Userinfo')
article = models.ForeignKey(to='Article')
is_up = models.BooleanField
class Comment(models.Model):
user = models.ForeignKey(to='Userinfo')
article = models.ForeignKey(to='Article')
content = models.CharField(max_length=255)
create_time = models.DateField(auto_now_add=True)
# 自关联,语义更明确
parent = models.ForeignKey(to='self',null=True)
- myform
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'
})
)
password = forms.CharField(max_length=8,min_length=3,label='密码',
error_messages={
'max_length':'密码最长8位',
'min_length':'密码最短3位',
'required':'密码不能为空'
},
widget=forms.widgets.PasswordInput(attrs={
'class':'form-control'
})
)
confirm_password = forms.CharField(max_length=8,min_length=3,label='确认密码',
error_messages={
'max_length':'确认密码最长8位',
'min_length':'确认密码最短3位',
'required':'确认密码不能为空'
},
widget=forms.widgets.PasswordInput(attrs={
'class':'form-control'
})
)
email = forms.EmailField(label='邮箱',error_messages={
'invalid':'邮箱格式不正确',
'required':'邮箱不能为空'
},widget=forms.widgets.EmailInput(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
- views
from django.shortcuts import render,HttpResponseRedirect
from app01 import myform
from app01 import models
from django.http import JsonResponse
# Create your views here.
def register(request):
# 生成一个空的forms对象
form_obj = myform.MyRegForm()
if request.method == 'POST':
back_dic = {'code':1000,'msg':''}
# 对用户提交的数据先进行校验 forms
# 直接使用forms组件的校验方法,校验整个的数据字典
form_obj = myform.MyRegForm(request.POST)
if form_obj.is_valid():
# 如果数据校验结果正确
clean_data = form_obj.cleaned_data # 获取正确的数据 4个键值对
# 将确认密码的键值对弹出,只剩余三个便于创建用户
clean_data.pop('confirm_password')
# 获取用户上传的文件
file_obj = request.FILES.get('avatar')
# 判断文件是否存在,用户是否上传,如果没有上传才会设置default头像
if file_obj:
clean_data['avatar'] = file_obj # 四个键值对
# 自动创建,使用**直接打散关键字参数
models.Userinfo.objects.create_user(**clean_data)
# 添加成功界面信息,及跳转
back_dic['msg'] = '注册成功'
back_dic['url'] = '/login/'
else:
back_dic['code'] = 2000
# 将错误信息返回给前端
back_dic['msg'] = form_obj.errors
# 返回给前端字典
return JsonResponse(back_dic)
return render(request,'register.html',locals())
- register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2 class="text-center">注册界面</h2>
{# input框的for循环显示#}
<form id="myform">
{% csrf_token %}
{% for foo in form_obj %}
<div class="form-group has-error">
{# label使得点击文本聚焦到input框中#}
<label for="{{ foo.auto_id }}">{{ foo.label }}</label>
{{ foo }}
<span class="error pull-right" style="color: red"></span>
</div>
{% endfor %}
{# 头像的标签框#}
<div class="form-group">
<label for="mdd">头像
<img src="/static/img/default.jpg" alt="" width="100px" style="margin-left: 10px" id="img">
</label>
{# 将input上传文件的框隐藏#}
<input type="file" name="avatar" id="mdd" style="display: none;">
</div>
{# 提交按钮#}
<input type="button" class="btn btn-success pull-right" value="注册" id="submit">
</form>
</div>
</div>
</div>
<script>
{#更换头像的图片域事件#}
$('#mdd').on('change',function () {
{#内置对象FileReader,完成文件的读取操作#}
let MyFileReader = new FileReader();
// 获取用户上传的文件对象
let fileObj = $(this)[0].files[0];
// 让文件阅读器读取文件
MyFileReader.readAsDataURL(fileObj); // 异步io操作
// 等待文件io操作读取完成再执行下面的代码
MyFileReader.onload = function () {
// 将读取之后的内容替换到img标签src属性中
$('#img').attr('src',MyFileReader.result)
}
});
{#提交按钮#}
$('#submit').click(function () {
// 将用户输入的数据全部发送给后端,普通的键值对和文件
let MyFormData = new FormData();
// FormData格式的数据传输,不停的添加键值对
{#MyFormData.append('','')#}
// 获取form表单里的所有input框的普通键值对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 { // 如果保存,循环拼接,获取报错的input框下面的span
$.each(data.msg,function(index,obj){
{#index 就是报错字段,obj是报错信息 数组的形式#}
// 获取报错字典,手动拼接该字段所对应的input框的id值
let targetId = '#id_' + index;
$(targetId).next().text(obj[0].parent().addClass('has-error'))
})
}
}
})
});
{#input框获取焦点事件#}
$('input').focus(function () {
$(this).next().text('').parent().removeClass('has-error')
})
</script>
</body>
</html>
1206 BBS注册的更多相关文章
- BBS注册功能
BBS注册功能 一.后端 1.组件校验数据 """ @author RansySun @create 2019-11-03-11:35 """ ...
- discuz bbs注册,登录流程整理!想打通bbs又不想读一遍代码可以参考一下
bbs 用户注册流程 第一步: /source/class/class_member.php: on_register注册入口 L602 左右 if(!$activation) {//不为空,说明用户 ...
- 史上最全的FTP网址
无帐号密码的为匿名登录 ftp://202.114.1.121 ftp://202.114.10.199 ftp://warez:cn.ftp@202.114.12.174 ftp://Music2: ...
- BBS(第一天)项目之 注册功能实现通过forms验证与 前端ajax请求触发查询数据库判断用户是否存在的功能实现
1.BBS项目之注册功能通过forms验证 from django import forms from blog.models import User from django.contrib.auth ...
- BBS - 表、登录、文件上传、注册
一.博客系统得表关系 models.py from django.db import models from django.contrib.auth.models import AbstractUse ...
- BBS论坛 注册功能
三.注册功能 # views.py文件 def register(request): back_dic = {'code': 100, 'msg': ''} form_obj = myforms.My ...
- 扩展auth_user字段、BBS需求分析、创建BBS数据库、注册页面搭建与用户头像展示及Ajax提交数据
昨日内容回顾 csrf跨站请求 1. SQL注入 2. xss攻击 3. csrf跨站请求 4. 密码加密(加盐) '''django中默认有一个中间件来验证csrf''' # 只针对post请求才验 ...
- BBS登录与注册功能
登录功能 视图函数 def my_login(request): if request.method == 'GET': return render(request, 'login.html') el ...
- bbs论坛注册功能(1)
分析项目需求创建表: STATICFILE_DIR = [ os.path.join(BASE_DIR,'static') #设置目录,bootstrip添加到目录中去,直接本地调用 ] # auth ...
随机推荐
- SpringBoot系列教程JPA之update使用姿势
原文: 190623-SpringBoot系列教程JPA之update使用姿势 上面两篇博文拉开了jpa使用姿势的面纱一角,接下来我们继续往下扯,数据插入db之后,并不是说就一层不变了,就好比我在银行 ...
- C++静态成员变量必须定义
静态成员变量在类中仅仅是声明,没有定义,所以要在类的外面定义,实际上是给静态成员变量分配内存,否则不能使用,编译不会通过. class A { public: static int a; //声明但未 ...
- 06 BootStrap前端开发框架(超级好用)
1.BootStrap概念: 一个前端开发的框架,Bootstrap,来自 Twitter,是目前很受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JavaScript 的,它简洁灵活 ...
- [转帖]Windows 7寿终正寝 为何Windows 10屡被吐槽它却无比经典?
Windows 7寿终正寝 为何Windows 10屡被吐槽它却无比经典? https://www.cnbeta.com/articles/tech/908897.htm 是的,一代经典操作系统Win ...
- java接入微信JS-SDK
在微信公众号开发中不可,jssdk的接入虽然不是必须,但是根据业务需求我们还是可能用到,下面是自己整理的关于java接入的jssdk的方法,这里是记录关于接入微信JS-SDK的准备工作,关于接入JS- ...
- Hbase面试题
hbase的特点 )hbase适合存储海量数据,是一个分布式的,基于列式存储的数据库,基于hadoop的hdfs存储,zookeeper进行管理. )hbase 适合存储半结构化或非结构化的数据,对于 ...
- day43——多表查询、Navicat工具的使用、pymysql模块
day43 多表查询 笛卡尔积--不经常用 将两表所有的数据一一对应,生成一张大表 select * from dep,emp; # 两个表拼一起 select * from dep,emp wher ...
- docker(一): 安装
开始 docker是一个可以帮助开发者使用容器(containers)开发.部署和运行应用程序的平台.llinux下使用容器部署系统称为containerization. container 是映像( ...
- 一天一个Linux命令,第三天cat命令
命令:cat (中文猫的意思) 解释:cat命令连接文件并打印到标准输出设备上(如显示器),cat经常用来显示文件的内容 注意:当文件较大时,文本在屏幕上迅速闪过(滚屏),用户往往看不清所显示的内容. ...
- AS3事件类型
Event事件类型: ACTIVATE 激活事件 DEACTIVATE 对象休眠事件 ADDED 可视对象添加事件 ADDED_TO_STAGE 可视对象添加到舞台事件 REMO ...