今日概要
1.点击注册
2.用户登入验证码
3.用户手机或邮箱/密码登入
4.项目管理
昨日内容回顾
1.项目规则
1.1视图、路由、静态文件等怎么去安排,去管理要准备好
1.2ajax 最简单的ajax
$.ajax({
url:"",
type:"",
data:{},
datatype:"JSON",
success:functino(res){
}
})
1.4在Form或者ModelForm中想要视图里面的数据
那么可以重写init方法,在视图里面把想要的如request传进来。在Form或者ModelForm接收即可。但是注意要在重写的init里面执行人家父类的init函数,父类的功能不可以少。
1.5Django-Redis
更方便的使用Redis
以上是day03重点!其余去前面的文章。
今日详细
1.点击注册
找到按钮:
image.png
1.1绑定事件,点击收集数据&ajax
重点serialize():
$("#regForm").serialize()
给form加一个属性,直接全部获取form组件的键值,太方便了!而且还会自动帮我们获取csrf_token的字段!所以在POST发送到后台就不会报csrf_token错了
image.png
ajax:
function bindClinkSubmit() {
$("#btnSubmit").click(function () {
//收集表单数据
//$("#regForm").serialize()给form加一个属性,直接全部获取form组件的键值,太方便了!
//发送到后台
$.ajax({
url:"{% url 'register' %}",
type:"POST",
data:$("#regForm").serialize(),
success:function (res) {
console.log(res)
}
})
// 数据ajax发送到后台
})
}
image.png
后台打印结果:
image.png
POST与GET的使用环境:
1.一般在更新、添加等POST
2.获取:GET
3.一般想要望后台传很多数据的时候,为了不导致URL太长,POST
但是规则是规则,具体怎么简单怎么来!
在这里不用在创建一个ModelForm,原因是我们之前的只是做了表单展示的功能,没有做及数据校验。这里就可以用了!
image.png
models里面
image.png
这样子可以加快查询速度!
1.2数据校验(每个字段都要校验)
用户名:
什么是钩子,说白了就是第二次校验,在去出username之后,判断他是不是在数据库里面已经有了!有的话就返回一个异常,终止执行,与add_errors不一样的raise功能!
def clean_username(self):
username = self.cleaned_data['username']
exists = models.UserInfo.objects.filter(username=username).exists()
if exists:
raise ValidationError('用户名已经存在!')
return username
对于邮箱:
虽然我们在models定义的是emailfiled,已经可以进行一个邮箱的校验,但是我们如果要判断不能重复,就只有自己定义钩子了,如下:
def clean_email(self):
email = self.cleaned_data['email']
exists = models.UserInfo.objects.filter(email=email).exists()
if exists:
raise ValidationError('邮箱已经存在!')
return email
对于校验,一般是谁在前面,谁优先校验!
image.png
也就是,当clear_confrim_password的函数里面只可以校验前三者。后面的还没机会校验呢,cleared_data里面还没有。
重视优先顺序!
对于密码与重复密码
直接在ModelForm:
password = forms.CharField(label='密码', min_length=8, max_length=64,
error_messages={
'min_length': "密码长度不能低于8个字符",
'max_length': "密码长度不能高于于64个字符"
},
如果密码都符合字段层面的校验:
那么就要使用钩子来进行校验密码是否一致了:
# 密码校验一致钩子
# 密码校验一致钩子
def clean_confrim_password(self):
pwd = self.cleaned_data['password']
confrim_pwd = self.cleaned_data['confrim_password']
if pwd != confrim_pwd:
raise ValidationError('两次输入的密码不一致!请核对再次输入!')
return confrim_pwd
手机号
def clean_mobile_phone(self):
mobile_phone = self.cleaned_data['mobile_phone']
exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
if exists:
raise ValidationError('手机号已注册!')
return mobile_phone
验证码:
def clean_code(self):
code = self.cleaned_data['code']
mobile_phone = self.cleaned_data['mobile_phone']
conn = get_redis_connection()
redis_code = conn.get(mobile_phone)
if not redis_code:
raise ValidationError('验证码失效或为发送,请发送!')
redis_str_code = redis_code.decode('utf-8')
if redis_str_code.strip() != code.strip():#取出两端空格!
raise ValidationError('验证码输入错误,请重新输入!')
Redis由于是一个键值对且是字节,所以要decode一下 测试的时候注意键要写,就是手机号要正确,不然报错!!!!!!!!血的教训。
1.3写入数据库
modelform.save() 很牛逼不仅保存还会自动把不数据库里面的字段剔除掉!!!!!
# 验证通过,写入数据库
instance = form.save()# modelform的牛逼之处了直接写入数据库并返回一条数据对象
这样就不用form.cleard_data.pop('没用的字段')来一个一个剔除
在使用写入:
models.UserInfo.objects.create(**data)
打伞的方式
密码加密
在util包里面定义一个py文件:
image.png
文件内容:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import uuid
import hashlib
from django.conf import settings
def md5(string):
""" MD5加密 """
hash_object = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))#去settings里面找加密的东西。
hash_object.update(string.encode('utf-8'))
return hash_object.hexdigest()
def uid(string):
data = "{}-{}".format(str(uuid.uuid4()), string)
return md5(data)
在form里面引入之后在进行如下操作!
# 密码
def clean_password(self):
pwd = self.cleaned_data['password']
# 密码加密,之后到form里面就是加密的了
return encrypt.md5(pwd)
# 密码校验一致钩子
def clean_confrim_password(self):
pwd = self.cleaned_data['password']#由于先执行,所以不用加密
confrim_pwd = encrypt.md5(self.cleaned_data['confrim_password'])#密文和密文比较
if pwd != confrim_pwd:
raise ValidationError('两次输入的密码不一致!请核对再次输入!')
return confrim_pwd
注册按钮ajax部分:
//注册按钮收集数据
function bindClinkSubmit() {
$("#btnSubmit").click(function () {
$(".error-msg").empty()//在再次点击之前将所有的span标签内容为空,避免歧义。
//收集表单数据
//$("#regForm").serialize()给form加一个属性,直接全部获取form组件的键值,太方便了!
//发送到后台
$.ajax({
url:"{% url 'register' %}",
type:"POST",
data:$("#regForm").serialize(),
dataType:'JSON',
success:function (res) {
if(res.status){
location.href = res.data//进行地址跳转
}
else {
$.each(res.error,function (key,value) {
//console.log(key,value)
$("#id_" + key).next().text(value[0])//获取错误信息,找到写入位置标签并写入
})
}
}
})
// 数据ajax发送到后台
})
}
后台:
注意这里还给前端传了一个data,指定了注册成功之后的跳转地址!
def register(request):
if request.method == 'GET':
form = RegisterModelForm()
return render(request, 'register.html', {'form': form})
# else:测试数据传输
# print(request.POST)
# return JsonResponse({})
form = RegisterModelForm(data=request.POST)#传入数据校验!
print('POST:', request.POST)
if form.is_valid():
# 验证通过,写入数据库,且让密码密文
form.save()# modelform的牛逼之处了直接写入数据库并返回一条数据对象
return JsonResponse({'status': True, 'data': '/login/'})
return JsonResponse({'satus': False, 'error': form.errors})
弄完之后:
按照格式填写即可:发现已经可以进行正常注册
image.png
自动跳转登入界面:
image.png











网友评论