前言
学无止境,无止境学。大家好,我是张大鹏,之前在抖音有5万多粉丝,不过现在不拍视频,专心写公众号了。笔者目前是高级Python工程师,之前是全栈工程师,主要擅长Golang和Python开发,对于Java,Vue,React也有一些研究。工作之余,喜欢学习和分享,希望能够通过此公众号”张大鹏520″,将自己学到的东西分享给大家,和大家一起交流,一起成长,一起进步。
今天要给大家分享的是《Django加Vue电商项目实战11 模型表单实现Ajax登录实战》,这是一个系列的教程,从零基础到项目实战。在本教程中,我会给大家介绍Django的模型表单实现Ajax登录的一个案例。主要接收JSON请求,校验JSON参数,响应JSON数据等。还会配套相关的练习,大家学完以后可以自行通过练习题巩固和加深对知识点的理解。
如果大家需要本教程的PDF电子书或者完整的源码,可以在文末找到获取方式哈。
模型表单实现Ajax登录实战
模型设计
from django.db import models
class UserBaseInfo(models.Model):
"""用户基本信息"""
id = models.AutoField(verbose_name='编号', primary_key=True)
username = models.CharField(verbose_name='用户名称', max_length=30)
password = models.CharField(verbose_name='密码', max_length=10)
age = models.IntegerField(verbose_name="年龄", default=1)
mobile = models.CharField(verbose_name="手机号码", max_length=11)
status = models.CharField(verbose_name='状态', max_length=1)
createdate = models.DateTimeField(verbose_name='创建日期', db_column='create_date', auto_now=True)
def __str__(self):
return f"UserBaseInfo(id={self.id},username={self.username},age={self.age},mobile={self.mobile},status={self.status})"
def __repr__(self):
return self.__str__()
class Meta:
managed = True
verbose_name = '人员基本信息'
db_table = 'user'
class ImgFile(models.Model):
"""文件模型"""
# 文件名称
name = models.CharField(verbose_name='名称', default='', max_length=30)
# 文件地址
headimg = models.FileField(verbose_name='路径', upload_to="uploads/")
def __str__(self):
return str(self.name)
class Meta:
verbose_name = '用户头像信息'
db_table = 'user_img'
添加用户信息
import os
import sys
# 设置目录查找路径
sys.path.insert(0, '../../')
# 设置Django配置信息
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'z06_django_form.settings')
import django
from django.utils import timezone
django.setup()
# 导入模型
from index.models import UserBaseInfo
import zdppy_random
if __name__ == "__main__":
# 先清空数据
UserBaseInfo.objects.all().delete()
# 准备数据
user_dict = {
"username": zdppy_random.random_ename(),
"password": zdppy_random.random_str(10),
"age": zdppy_random.random_int(20, 40),
"mobile": zdppy_random.random_phone(),
"status": str(zdppy_random.random_int(0, 2)),
"createdate": timezone.now(),
}
# 执行创建
UserBaseInfo.objects.create(**user_dict)
# 查询结果
all = UserBaseInfo.objects.all().values()
print(all)
表单设计
import re
from django import forms
from django.core.exceptions import ValidationError
from .models import UserBaseInfo
def age_validate(value):
"""自定义年龄校验器"""
if value < 1 | value > 120:
raise ValidationError('年龄范围为1-120岁')
def mobile_validate(value):
"""自定义手机校验器"""
mobile_re = re.compile(
r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('手机号码格式错误')
class UserBaseInfoForm(forms.Form):
"""用户信息"""
# 状态
STATUS = ((None, '请选择'), (0, '正常'), (1, '无效'),)
# 用户名
username = forms.CharField(label="用户名", min_length=6,
error_messages={
'required': '用户姓名不能为空',
'min_length': '长度最少6位',
'invalid': '输入正确的用户姓名'
})
# 年龄
age = forms.IntegerField(label="年龄", initial=1, validators=[age_validate],
error_messages={
'required': '年龄不能为空',
})
# 用户状态
status = forms.ChoiceField(label="用户状态", choices=STATUS,
error_messages={
'required': '用户状态不能为空',
})
# 创建时间
createdate = forms.DateTimeField(label="创建时间", required=False)
class UserInfoForm(forms.Form):
"""用户信息表单"""
# 状态
STATUS = ((None, '请选择'), (0, '正常'), (1, '无效'),)
# 用户名
username = forms.CharField(label="用户名", min_length=6,
widget=forms.widgets.TextInput(
attrs={'class': 'form-control', 'placeholder': "请输入用户名"}))
# 密码
password = forms.CharField(label="密码", min_length=6, max_length=10,
widget=forms.widgets.PasswordInput(
attrs={"class": "password"},
render_value=True))
# 年龄
age = forms.IntegerField(label="年龄", initial=1)
# 手机号
mobile = forms.CharField(label="手机号码")
# 用户状态
status = forms.ChoiceField(label="用户状态", choices=STATUS)
# 创建时间
createdate = forms.DateTimeField(label="创建时间", required=False)
class UserInfoValidateForm(forms.Form):
"""用户信息校验表单"""
# 状态
STATUS = ((None, '请选择'), (0, '正常'), (1, '无效'),)
# 用户名
username = forms.CharField(label="用户名", min_length=6,
widget=forms.widgets.TextInput(
attrs={'class': 'form-control', 'placeholder': "请输入用户名"}),
# 错误信息
error_messages={
'required': '用户姓名不能为空',
'min_length': '长度最少6位',
'invalid': '输入正确的用户姓名'
})
# 密码
password = forms.CharField(label="密码", min_length=6, max_length=10,
widget=forms.widgets.PasswordInput(
attrs={"class": "password"}, render_value=True),
error_messages={
'max_length': '密码最长10位',
'required': '密码不能为空',
'min_length': '密码最少6位'
})
# 年龄
age = forms.IntegerField(label="年龄", initial=1, validators=[age_validate],
error_messages={
'required': '年龄不能为空',
})
# 手机号
mobile = forms.CharField(label="手机号码", validators=[mobile_validate],
error_messages={
'required': '手机号码不能为空',
})
# 状态
status = forms.ChoiceField(label="用户状态", choices=STATUS,
error_messages={
'required': '用户状态不能为空',
})
# 创建时间
createdate = forms.DateTimeField(label="创建时间", required=False)
class ImgFileForm(forms.Form):
"""图片上传表单"""
# 图片名称
name = forms.CharField()
# 文件地址
headimg = forms.FileField()
class UserBaseInfoModelForm(forms.ModelForm):
"""用户基本信息模型表单"""
# 确认密码,模型中没有的字段
confirm_password = forms.CharField(
label='确认密码', widget=forms.PasswordInput(render_value=True),
error_messages={
'required': '密码不能为空',
})
class Meta:
# 定义关联模型
model = UserBaseInfo
# 定义需要在表单中展示的字段。
fields = ['username', 'password',
'confirm_password', 'age', 'mobile', 'status']
# 如果要显示全部字段,可以如下设置
# fields="__all__"
# 如果Models中定义了名称,这里不用再定义
labels = {
"age": "最佳年龄",
"mobile": "手机信息",
}
# 表单自定义
widgets = {
# 文本框渲染为密码输入框
"password": forms.widgets.PasswordInput(attrs={"class": "password"}, render_value=True),
"confirm_password": forms.widgets.PasswordInput(attrs={"class": "password"}, render_value=True)
}
# 错误信息
error_messages = {
"username": {
'required': '用户姓名不能为空',
'min_length': '长度最少6位',
'invalid': '输入正确的用户姓名'
},
"password": {
'max_length': '密码最长10位',
'required': '密码不能为空',
'min_length': '密码最少6位'
},
"age": {
'required': '年龄不能为空',
},
"mobile": {
'required': '手机号码不能为空',
},
"status": {
'required': '用户状态不能为空',
}
}
# 校验手机号码的局部钩子函数
def clean_mobile(self):
"""校验手机号"""
mobile = self.cleaned_data.get('mobile')
print(mobile)
mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(mobile):
raise ValidationError('手机号码格式错误')
return mobile
# 全局钩子函数
def clean(self):
"""校验密码"""
password = self.cleaned_data.get("password")
confirm_password = self.cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError("二次密码输入不一致")
路由设计
from django.urls import path
from . import views
app_name = 'index'
urlpatterns = [
path('', views.index, name='index'),
# 文件上传
path('upload/', views.upload, name='upload'),
# 用户信息
path('userinfo/', views.userinfo, name='userinfo'),
# 表单数据校验
path('validate/', views.validate, name='validate'),
# 上传图片
path('upload_img/', views.upload_img, name='upload_img'),
# 模型表单数据校验
path('validate_model/', views.validate_model, name='validate_model'),
# ajax实现用户登录
path('ajax_login/', views.ajax_login, name='ajax_login'),
]
视图函数
import os
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from .forms import UserInfoForm, UserInfoValidateForm, ImgFileForm, UserBaseInfoModelForm
from .models import ImgFile, UserBaseInfo
def index(request):
return render(request, "index.html")
def upload(request):
"""
文件上传
"""
if request.method == "GET":
return render(request, "upload.html")
# 请求方法为POST时,进行处理。文件上传为POST请求。
if request.method == "POST":
# 获取上传的文件,如果没有文件,则默认为None
file = request.FILES.get("file", None)
if file:
# 准备文件夹
path = 'media/uploads/'
if not os.path.exists(path):
os.makedirs(path)
# 分块写入文件
dest = open(os.path.join(path + file.name), 'wb+')
for chunk in file.chunks():
dest.write(chunk)
dest.close()
return HttpResponse("上传完成!")
else:
return HttpResponse("没有上传文件!")
def userinfo(request):
"""用户信息"""
if request.method == "GET":
user_info_form = UserInfoForm()
return render(request, "userinfo.html", {'form_obj': user_info_form})
def validate(request):
"""表单校验"""
if request.method == "GET":
user_info_form = UserInfoValidateForm()
return render(request, "validate.html", {'form_obj': user_info_form})
else:
# 提取上传的数据
f = UserInfoValidateForm(request.POST)
# 进行校验
if f.is_valid():
print(f.clean())
print(f.cleaned_data["username"])
print(f.data)
else:
errors = f.errors
print(errors)
return render(request, "validate.html", {'form_obj': f, 'errors': errors})
return render(request, "validate.html", {'form_obj': f})
def upload_img(request):
if request.method == "GET":
# 渲染页面
f = ImgFileForm()
return render(request, "upload_img.html", {'form_obj': f})
else:
# 校验表单数据并保存
f = ImgFileForm(request.POST, request.FILES)
if f.is_valid():
# 获取数据
name = f.cleaned_data['name']
headimg = f.cleaned_data['headimg']
# 创建文件模型并保存
userimg = ImgFile()
userimg.name = name
userimg.headimg = headimg
userimg.save()
# 渲染页面
print("上传成功")
return render(request, "upload_img.html", {'form_obj': f, 'user': userimg})
def validate_model(request):
"""模型表单校验"""
if request.method == "GET":
# 渲染页面
a = UserBaseInfo.objects.get(id=1)
myform = UserBaseInfoModelForm(instance=a)
return render(request, "validate_model.html", {'form_obj': myform})
else:
# 获取表单数据并校验
f = UserBaseInfoModelForm(request.POST)
if f.is_valid():
# 模型表单可以直接调用保存方法
f.save()
else:
errors = f.errors
print(errors)
return render(request, "validate_model.html", {'form_obj': f, 'errors': errors})
return render(request, "validate_model.html", {'form_obj': f})
def ajax_login(request):
if request.method == "GET":
return render(request, "ajax_login.html")
# 获取用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# 判断并返回json数据
if username == 'admin' and password == '123456':
return JsonResponse({'code': 1, "msg": "登陆成功"})
else:
return JsonResponse({'code': 0, "msg": "登陆失败"})
模板
首页模板:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Django表单示例</title>
</head>
<body>
<h1>Django表单示例</h1>
<h2>路由列表</h2>
<ul>
<li><a href="{% url 'index:index' %}">/</a></li>
<li><a href="{% url 'index:upload' %}">/upload/</a></li>
<li><a href="{% url 'index:userinfo' %}">/userinfo/</a></li>
<li><a href="{% url 'index:validate' %}">/validate/</a></li>
<li><a href="{% url 'index:upload_img' %}">/upload_img/</a></li>
<li><a href="{% url 'index:validate_model' %}">/validate_model/</a></li>
<li><a href="{% url 'index:ajax_login' %}">/ajax_login/</a></li>
</ul>
</body>
</html>
★
注意:需要读者提前从网站下载jquery.js放到static目录。
”
登录页模板:
用户名:<input type="text" id="username"></input>
密码:<input type="password" id="password"></input>
{% csrf_token %}
<button id="submit">提交</button>
{% load static %}
<script src="{% static 'jquery.js' %}"></script>
<script>
$("#submit").click(function () {
$.ajax({
url: "/ajax_login/", //后端请求地址
type: "POST", //请求方式
data: {//请求参数
username: $("#username").val(),
password: $("#password").val(),
"csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()
},
//请求成功后操作
success: function (data) {
console.log(data)
alert(data.msg)
},
//请求失败后操作
error: function (jqXHR, textStatus, err) {
console.log(arguments);
},
})
})
</script>
测试
测试地址:http://192.168.33.13:8000/ajax_login/
结语
关注我不迷路,欢迎关注我的微信公众号”张大鹏520″,如果您对此文章感兴趣,欢迎点赞收藏,留言评论。
文中所有代码,只需要打赏20元,然后留言评论“已打赏”,即可获取哦。
本文的PDF电子书版,只需要打赏3元,然后留言评论“已打赏”,即可获取哦。
写文章不容易,不喜勿喷哈,如果有想要学编程,学项目,或者在工作中有项目难以单独完成需要提供帮助的同学,欢迎私信我哈。生活不易,想要利用学到的编程知识,业余赚点零花钱。
接项目:网站开发,APP开发,各种管理系统开发。
带徒弟:Python编程教学,Golang编程教学,前端编程教学。
谢谢您!!!
原文始发于微信公众号(张大鹏520):Django加Vue电商项目实战11 模型表单实现Ajax登录实战
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/48603.html