Django加Vue电商项目实战11 模型表单实现Ajax登录实战

前言

学无止境,无止境学。大家好,我是张大鹏,之前在抖音有5万多粉丝,不过现在不拍视频,专心写公众号了。笔者目前是高级Python工程师,之前是全栈工程师,主要擅长Golang和Python开发,对于JavaVue,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(2040),
        "mobile": zdppy_random.random_phone(),
        "status": str(zdppy_random.random_int(02)),
        "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()
            },
            //请求成功后操作
            successfunction (data{
                console.log(data)
                alert(data.msg)
            },
            
            //请求失败后操作
            errorfunction (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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!