Django 系列博客(十四)

Django 系列博客(十四)

前言

本篇博客介绍在 html 中使用 ajax 与后台进行数据交互。

什么是 ajax

ajax(Asynchronous Javascript And XML)翻译成中文就是‘’异步 JavaScript 和 XML‘’。即使用 JavaScript 语言与服务器进行异步交互,传输的数据为 XML(现在更多地使用 json)。

  • 同步交互:客户端发出一个请求后,需要等待服务器响应结束,才能发出第二个请求;
  • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,也能发出第二个请求。

ajax 除了异步的特点外,还有一个就是:浏览器页面局部刷新。在页面没有进行刷新的情况下进行数据交互。

优点:

  • ajax 使用JavaScript 技术向服务器发送异步请求;
  • ajax 无需刷新整个页面。

基于 jQuery 的 ajax 实现

前端代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="/static/jquery-3.3.1.js"></script>

    <title>regist</title>
{#    <link rel="stylesheet" href="/static/jquery-3.3.1.js">#}
</head>
<body>
<p>用户:<input type="text" id="name"></p>
<p>密码:<input type="password" id="pwd"></p>
<p>确认密码:<input type="password" id="tpwd"></p>
<input type="button" id="submit" value="提交"><span id="error"></span>
</body>

<script>

    $(‘#submit‘).click(function () {
        console.log($(‘#submit‘));
        {#$.ajax({#}
        {#    url:‘/regist/‘,#}
        {#    type:‘post‘,#}
        {#    data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd")},#}
        {#    success:function (data) {#}
        {#        console.log(data)#}
        {#    }#}
        $.ajax({
            url:‘/regist/‘,
            type:‘post‘,
            data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd").val()},
            success:function (data) {
                console.log(data)
            }
        })

    })
</script>
</html>

后端代码

from django.http import JsonResponse
from django.shortcuts import render, redirect
from app01.models import *

# Create your views here.

def wrapper(func):
    def inner(*args, **kwargs):
        if args[0].method == ‘GET‘:
            return func(*args, **kwargs)
        elif kwargs[‘contentType‘] == ‘application/json‘:
            import json
            args[0].POST = json.loads(args[0].body)
            return func(*args, **kwargs)
        else:
            return func(*args, **kwargs)
    return inner

import json
# json.loads()

def regist(request):
    dic = {‘status‘: 200, ‘msg‘: None}
    print(request.body)
    if request.method == ‘GET‘:
        return render(request, ‘regist.html‘)
    else:
        print(‘/////‘)
        print(request.POST, ‘dddd‘)
        name = request.POST.get(‘name‘)
        pwd = request.POST.get(‘pwd‘)
        tpwd = request.POST.get(‘tpwd‘)

        user = UserInfo.objects.filter(name=name).first()
        if user:
            dic[‘status‘] = 100
            dic[‘msg‘] = ‘用户已存在‘
            return JsonResponse(dic)
        else:
            if name and pwd and tpwd:
                if pwd == tpwd:
                    UserInfo.objects.create(name=name, pwd=pwd)
                    dic[‘msg‘] = ‘注册成功‘
                    return JsonResponse(dic)
                else:
                    dic[‘status‘] = 101
                    dic[‘msg‘] = ‘两次密码不一样‘
                    return JsonResponse(dic)
            else:
                dic[‘status‘] = 101
                dic[‘msg‘] = ‘密码不正确‘
                return JsonResponse(dic)

@wrapper
def login(request):
    dic = {‘status‘: 200, ‘msg‘: None}
    if request.method == ‘GET‘:
        return render(request, ‘login.html‘)
    else:
        name = request.POST.get(‘name‘)
        pwd = request.POST.get(‘pwd‘)

        user = UserInfo.objects.filter(name=name).first()
        if not user:
            dic[‘status‘] = 100
            dic[‘msg‘] = ‘用户不存在,请注册‘
            return JsonResponse(dic)
        else:
            if pwd == user.pwd:
                dic[‘msg‘] = ‘登陆成功‘
                return JsonResponse(dic)
            else:
                dic[‘status‘] = 101
                dic[‘msg‘] = ‘密码错误‘
                return JsonResponse(dic)

js代码

$("#submit3").click(function () {
            $.ajax({
                url: ‘/auth/‘,
                type: ‘post‘,
                data: {
                    ‘user‘: $("#id_name").val(),
                    ‘password‘: $(‘#id_password‘).val()
                },

                success: function (data) {
                    {#console.log(data)#}
                    var data=JSON.parse(data)
                    if (data.user){
                        location.href=‘https://www.baidu.com‘
                    }else {
                        $(".error").html(data.message).css({‘color‘:‘red‘,‘margin-left‘:‘20px‘})
                    }
                }

            })
        }
    )

文件上传

请求头

  1. application/x-www-form-urlencoded

这是最常见的 POST 提交数据的方式了。浏览器的原生

表单,如果不设置 enctype 属性,那么最终会以 application/x-www-form-urlencoded方式提交数据。类似于下面:

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

请求体
  1. multipart/form-data

当我们使用表单上传文件时,必须让表单的 enctype 等于multipart/form-data。

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="user"

yuan
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以--boundary 开始,紧接着是内容描述信息,然后回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以--boundary--表示结束。

这种方式一般用于上传文件,各大服务端语言也有很好的支持。

这两种POST 提交的方式,都是浏览器原生支持的,而且先阶段标准中原生表单也只支持这两种方式(通过元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded)。随着越来越多的web站点尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

  1. application/json

application/json是另外一种请求头,不过更多的是作为响应头,因为 json 格式的数据时通用数据格式。不过目前也用来作为请求头,用来告诉服务器端主体是序列化后的 json 字符串。由于 json 规范的流行,除了低版本的 IE 之外的各大浏览器都原生支持 json.stringfy,服务器端语言也都有处理 json数据的函数,使用 json 不会遇到什么麻烦。

json 格式支持比键值对复杂的多的结构化数据,这点对数据传输很有用。

基于form表单上传文件

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="" method="post" enctype="multipart/form-data">
    <p>用户名:<input type="text" name="name"></p>
    <input type="file" name="myfile">
{#    <input type="file" name="myfile2">#}
    <input type="submit" value="提交">

</form>

</body>
</html>

后端代码

class UploadFile(View):

    def get(self, request):
        return render(request, ‘upload_file.html‘)

    def post(self, request):
        file = request.FILES.get(‘myfile‘)
        # print(file[‘file‘])
        from django.core.files.uploadedfile import InMemoryUploadedFile
        print(time.time())
        filename = str(time.time()).split(‘.‘)[0] + file.name
        with open(filename, ‘wb‘) as f:
            for line in file:
                f.write(line)
        return HttpResponse(‘上传成功‘)

基于ajax 的文件上传

前端代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>uploadfile</title>
    <script src="/static/jquery-3.3.1.js"></script>
</head>
<body>
<p>用户名:<input type="text" id="name"></p>
<p>选择文件:<input type="file" id="my_file"></p>
<button id="btn">上传</button><span id="msg"></span>
</body>

<script>
    $(‘#btn‘).click(function () {
        var myfile = $(‘#my_file‘)[0].files[0];
        var formdata = new FormData();
        formdata.append(‘name‘, $(‘#name‘).val());
        formdata.append(‘myfile‘, myfile);
        $.ajax({
            url:‘/uploadfile/‘,
            type:‘post‘,
            processData:false, // 告诉 jQuery 不要处理发送的数据
            contentType:false, // 告诉 jQuery 不要设置 Content-Type 请求头
            data:formdata,
            success:function (data) {
                console.log(data);
                $(‘#msg‘).text(data)
            }
        })
    })

</script>
</html>

后端代码

MEDIA_PATH = ‘/Users/jingxing/Django/homework/paging/media‘

def uploadfile(request):
    if request.method == ‘GET‘:
        return render(request, ‘uploadfile.html‘)
    else:

        myfile = request.FILES.get(‘myfile‘)
        print(myfile)
        filepath = os.path.join(MEDIA_PATH, myfile.name[32:-3]+‘jpg‘)
        with open(filepath, ‘wb‘) as f:
            for line in myfile:
                f.write(line)
        FileInfo.objects.create(name=request.POST.get(‘name‘), filepath=filepath)
        return HttpResponse(‘上传成功‘)

ajax 提交 json 格式数据

前端代码

$(‘#submit1‘).click(function () {
        postdata={name1:$("#name").val(),pwd2:$("#pwd").val()}
        $.ajax({
            url:‘/loginjson/‘,
            type:‘post‘,
            // 指定提交的编码格式是json格式,
            contentType:‘application/json‘,
            data:JSON.stringify(postdata),
            // data:postdata,
            // data:‘123‘,
            success:function (data) {
                console.log(data)

            }
        })
    })

后端代码

def loginjson(request):
    dic={‘status‘:100,‘msg‘:None}
    if request.method==‘POST‘:
        print(request.POST)
        print(request.GET)
        print(request.body)
        xx=request.body.decode(‘utf-8‘)
        # re是个字典{"name1":"lqz","pwd2":"123"}
        re=json.loads(xx)
        request.POST=11

        print(request.POST)
        #
        #
        # name=re.get(‘name1‘)
        # pwd=re.get(‘pwd2‘)
        # print(name)
        # print(pwd)
        return HttpResponse(‘ok‘)

后端返回 json 数据

前端代码

$(‘#submit‘).click(function () {
        $.ajax({
            url:‘/login/‘,
            type:‘post‘,
            data:{name1:$("#name").val(),pwd2:$("#pwd").val()},
            success:function (data) {
                //后台用JsonResponse返回数据
                //data 就会被转成字典
                console.log(data)
                console.log(typeof data)
                //JSON.parse(data) 把字符串类型转成字典
                data=JSON.parse(data)
                {#JSON.stringify()#}
                console.log(typeof dat1)
                if(data.status == 100){
                    //成功,跳转到指定页面
                    //location.href=地址,前端就会跳转到指定的url
                    alert(data.msg)
                    //$("#error").text(data.msg+‘正在跳转‘)
                    //location.href=data.url
                }else{
                    $("#error").text(data.msg)
                }

            }
        })
    })

后端代码

def login(request):
    dic={‘status‘:100,‘msg‘:None}
    if request.method == ‘GET‘:
        return render(request, ‘login.html‘)
    # if request.is_ajax():
    if request.method==‘POST‘:
        name=request.POST.get(‘name1‘)
        pwd=request.POST.get(‘pwd2‘)
        if name==‘lqz‘ and pwd==‘123‘:
            dic[‘msg‘] = ‘登陆成功‘
            # 想让前端跳转
            # dic[‘url‘]=‘http://www.baidu.com‘
            dic[‘url‘]=‘/test/‘
        else:
            # 返回json格式字符串
            dic[‘status‘]=101
            dic[‘msg‘]=‘用户名或密码错误‘
        # return JsonResponse(dic)
        return HttpResponse(json.dumps(dic))

Django内置的序列化数据方法

from django.core import serializers

def test(request):
    book_list = Book.objects.all()
    ret = serializers.serialize(‘json‘, book_list)
    return HttpResponse(ret)

原文地址:https://www.cnblogs.com/zuanzuan/p/10294294.html

时间: 2024-11-06 16:40:11

Django 系列博客(十四)的相关文章

Django搭建博客网站(四)

Django搭建博客网站(四) 最后一篇主要讲讲在后台文章编辑加入markdown,已经在文章详情页对markdown的解析. Django搭建博客网站(一) Django搭建博客网站(二) Django搭建博客网站(三) 要用到的package django-pagedown markdown2 django-pagedown用来在后台生成markdown编辑器,markdown2则是用来将markdown解析成html显示在网页上. install $ pip install django-

Django 系列博客(二)

Django 系列博客(二) 前言 今天博客的内容为使用 Django 完成第一个 Django 页面,并进行一些简单页面的搭建和转跳. 命令行搭建 Django 项目 创建纯净虚拟环境 在上一篇博客中已经安装好了虚拟环境,所以用虚拟环境来安装指定版本的 Django.为了可以从头到尾的走一遍流程,我重新创建了一个虚拟环境. 激活虚拟环境并安装 Django 首先进入虚拟环境路径下的 bin 目录 使用命令激活虚拟环境 安装指定版本 Django 首先使用 pip3 list 命令查看 可以看到

Django 系列博客(七)

Django 系列博客(七) 前言 本篇博客介绍 Django 中的视图层中的相关参数,HttpRequest 对象.HttpResponse 对象.JsonResponse,以及视图层的两种响应方式 CBV 和 FBV,还有简单的文件上传. 视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以.无论视图本身包含什么逻辑,都要返回

Django 系列博客(十一)

Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系(one-to-one). 出版商模型:出版商有名称,所在城市. 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一

Django 系列博客(十三)

Django 系列博客(十三) 前言 本篇博客介绍 Django 中的常用字段和参数. ORM 字段 AutoField int 自增列,必须填入参数 primary_key=True.当 model 中如果没有自增列,则会自动创建一个列名为 id 的列. IntegerField 一个整数类型,范围在-2147483648 to 2147483647. CharField 字符类型,必须提供max_length参数, max_length表示字符长度. DateField 日期字段,日期格式

JavaScript 系列博客(四)

JavaScript 系列博客之(四) 前言 本篇介绍 JavaScript 中的对象.在第一篇博客中已经说到 JavaScript 是一种''对象模型''语言.所以可以这样说,对象是 JavaScript 语言的核心概念,也是最重要的数据类型. 概述 生成方法 在 JavaScript 中声称对象相当方便,直接定义一个空字典就 ok.想要添加属性或者方法的话可以在定义结束之后动态添加.注意:对象时无序的复合数据集合. 上面代码中,大括号就可以直接定义一个对象,被赋值给变量 a,所以 a 就指向

django参考博客学习

网上发现其他人的一个django系列博客,和我学的一样是黑马的,写的挺不错的,转载学习一下 https://blog.csdn.net/u014745194/article/category/6989943 原文地址:https://www.cnblogs.com/regit/p/9023081.html

Django搭建简易博客教程(四)-Models

原文链接: http://www.jianshu.com/p/dbc4193b4f95 Django Model 每一个Django Model都继承自django.db.models.Model 在Model当中每一个属性attribute都代表一个database field 通过Django Model API可以执行数据库的增删改查, 而不需要写一些数据库的查询语句 设置数据库 Django项目建成后, 默认设置了使用SQLite数据库, 在my_blog/my_blog/setting

关于算法导论系列博客的说明

本系列博客主要为练习<算法导论(第三版)>的记录.发表目的在于希望通过大家的帮助,不断地改进程序,使其在时间和空间方面效率不断提高.由于水平有限,错误在所难免.但是,我一定尽力消除.另外, 欢迎大家指出错误,提出宝贵的建议,感谢大家的指点和帮助. 特别注明: 你们的评论对我是一种莫大的鼓励,哪怕一个字也好,万分感谢. 在开始之前,对各练习的程序作出统一说明,以后不再重复. 一  程序一般用C语言写,编译为GCC. 二   程序一般为子程序的形式,不提供调用主程序,只完成要求的功能. 三   不