任务
计划完成一款帮助学习计划管理的小程序,实现其中的登录功能。
难点:由于采用蓝鲸的开发平台,其中的登录模块已经经过设定,需要进行重建。
过程
Model
首先定义基于Django的用户模块User之上的应用基础用户模块baseUser,数据表如下:
from django.contrib.auth.models import User
#from blueapps.account.models import User
但在蓝鲸SaaS平台中已经被改写,因此引入被改写后的User
class baseUser(models.Model):
user=models.OneToOneField(User,models.CASCADE)
phone=models.CharField(max_length=50,null=True,blank=True)
email=models.CharField(max_length=50,null=True,blank=True)
avatar=models.CharField(max_length=50,null=True,blank=True)
其中user信息基于用户模块,可以完成密码的加密,另外加入电话、邮箱与头像信息。
View
用户登录主要包括注册与登录两部分,首页是登录界面,可以链接到注册界面,相反亦然:
这里主要利用文章Django中的Form组件中的方法,可以快捷进行数据交互,组件的特性有:
- 生成页面的HTML标签及样式
- 对用户提交的数据进行校验
- 自动生成错误信息
- 保留上次输入信息
一个表单实例
利用CBV(Class Base View)
形式进行视图函数书写
url.py
url(r'^form$',views.Form.as_view()),
view.py
继承Form组件
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
class TestForm(forms.Form):
# 用户名
username = forms.CharField(
min_length=6,#设置最小长度
max_length=12,#设置最大长度
label="用户名",#设置标签名
#错误信息提示设置
error_messages={
"min_length": "用户名不能少于6位",
"max_length":'用户名不能超过12位',
"required": "用户名不能为空"
},
#插件设置
widget=forms.widgets.TextInput(
attrs={"class": "form-control"}# 给生成的标签添加属性
)
)
类视图
class Form(views.View):
def get(self,request):
#实例化TestForm
test_obj=TestForm()
return render(request, 'mechat/form.html', {'test_obj': test_obj})
def post(self,request):
# 前后端交互信息
res = {'code': 0}
# 实例化form类,将前端得到的数据提交到实例中
test_obj = TestForm(request.POST)
# 利用form内置方法校验前端得到的数据
if test_obj.is_valid():
res['code']=1
res['msg']='success'
else:
res['msg']=test_obj.errors
return JsonResponse(res)
form.html
<body>
<body>
<form>
{% csrf_token %}
{% for field in test_obj %}
<div class="form-group">
<label class="letleft" for="field.id_for_label">{{ field.label }}</label>
{{ field }}
<span class="err-msg"></span>
</div>
{% endfor %}
</form>
<button onclick="send_ajax()">提交</button>
</body>
JS
<script>
function send_ajax(){
let formdata = new FormData();
formdata.append('username', $('#id_username').val());
//设置csrftoken来防止跨站csrf攻击
formdata.append('csrfmiddlewaretoken', $("[name='csrfmiddlewaretoken']").val());
$.ajax({
url: '{{SITE_URL}}mechat/form',
type: 'POST',
processData: false, //不让jQuery处理我的obj
contentType: false, // 不让jQuery设置请求的内容类型
data: formdata,
success: function(res){
console.log(res)
console.log(res['msg'])
if (res.code === 0) {
$.each(res.msg, function (k, v) {
//添加错误提示样式
$("#id_" + k).next().text(v[[0]]).parent().addClass('err-msg')
})
}
}
});
}
</script>
所做处理
- 将蓝鲸SaaS的登录中间件注释掉
- 增加验证backends的方式(默认方式)
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
通过比对登录用户名与密码是否存在于数据库中,利用登录验证模块的authenticate()
进行鉴权登录
登录函数
def login(request):
if request.method =='POST':
# post请求接受验证数据
username = request.POST.get('username')
password = request.POST.get('password')
if(username==''):
return JsonResponse({"result":False,"message":'请输入用户名'})
elif(password==''):
return JsonResponse({"result":False,"message":'请输入密码'})
user=auth.authenticate(username=username,password=password)
if user is not None and user.is_active:
# 验证通过进行登录
auth.login(request,user) # session cookie
request.session['username'] = username
return JsonResponse({"result":True,"message":'登录成功'})
知识点
Python中的*args和**kwargs- 百晓生的文章 – 知乎
- args 是 arguments 的缩写,表示位置参数;
- kwargs 是 keyword arguments 的缩写,表示关键字参数。
- 这是 Python 中可变参数的两种形式,并且 *args 必须放在 **kwargs 的前面,因为位置参数在关键字参数的前面。
def test_kwargs(first, *args, **kwargs):
print('Required argument: ', first)
print(type(kwargs))
for v in args:
print ('Optional argument (args): ', v)
for k, v in kwargs.items():
print ('Optional argument %s (kwargs): %s' % (k, v))
test_kwargs(1, 2, 3, 4, k1=5, k2=6)
输出结果
Required argument: 1 <class 'dict'> Optional argument (args): 2 Optional argument (args): 3 Optional argument (args): 4 Optional argument k1 (kwargs): 5 Optional argument k2 (kwargs): 6