09.Django与Ajax


Django与ajax(入门)

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步JavaScript和XML”。是指一种创建交互式,快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。

通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新,这意味着在不重新加载整个网页页面的情况下,对网页的部分内容进行更新

AJAX是一种用于快速动态网页的技术

传统的网页(不使用AJAX)如果需要更新内容,必须重新加载整个页面,而前面谈到AJAX是什么,其主要就是异步提交,那我们来聊聊同步和异步提交的区别

同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,客户才可以使用网页

异步提交:当用户发送请求时,当前页面可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来

AJAX的工作原理:

相当于在用户和服务器之间加了一个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像一些数据验证和数据处理等都交给ajax引擎自己来做,只有确定需要从服务器读取数据时再由AJAX引擎代为向服务器提交请求

客户端发送请求,请求交给xhr,xhr把请求提交给服务,服务器进行业务处理,服务器响应数据交给xhr对象,xhr对象接收数据,由javascript把数据写到页面上,如下图所示:

要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:

1.创建XMLHttpRequest对象,即创建一个异步调用对象.
2.创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
3.设置响应HTTP请求状态变化的函数.
4.发送HTTP请求.
5.获取异步调用返回的数据.
6.使用JavaScript和DOM实现局部刷新.

ps:AJAX传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)
  基本上web页面都有很多ajax请求

"https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
class="col-md-6 col-md-offset-3">
class="panel panel-primary">
class="panel-heading">

class="panel-title">网页

class="panel-body">

class="text-center">登录

"" method="post">

用户名:"text" id="id_username" class="form-control">

密码:"password" id="id_password" class="form-control">

"id_btn" type="button" value="提交" class="btn btn-primary btn-block">class="error" style="color: red">
login.html login.html

2 上传文件(ajax和form两种方式)

1 http --post--请求,有编码格式,主流有三种
    urlencoded :默认的----》从request.POST取提交的数据
    form-data :上传文件的----》从request.POST取提交的数据,request.FILES中取文件
    json      :ajax发送json格式数据-----》request.POST取不出数据了
    
2 使用ajax和form表单,默认都是urlencoded格式
3 如果上传文件:form表单指定格式,ajax要使用Formdata对象 4 如果编码方式是urlencoded格式,放到body体中数据格式如下 username=lqz&password=123 5 如果是formdata编码格式,body体中是:两部分,数据和文件 6 如果是json格式,body体中的格式是:就是json格式字符串 -注意:注意:注意:如果这种格式,request.POST取不到值了

form表单上传文件

urlpatterns = [ 
    url(r'^file_upload/', views.file_upload),    
]
urls.py
def file_upload(request):
    if request.method == 'GET':
        return render(request,'file_upload.html')
    else:
        name = request.POST.get('name')
        myfile = request.FILES.get('myfile') # 拿到文件
        print(type(myfile)) # 查看类型
        with open(myfile.name, 'wb') as f:
            for line in myfile:
                f.write(line)

        return HttpResponse('上传成功')

views.py
views.py

"en">

    "UTF-8">
    Title
    



form表单上传文件

"" method="post" enctype="multipart/form-data">

用户名:"text" name="name">

文件:"file" name="myfile">

"submit" value="提交"> file_upload.html
file_upload.html

ajax 上传文件


"en">

    "UTF-8">
    Title
    



ajax上传文件

用户名:"text" id="id_name">

文件:"file" id="id_myfile">

file_upload.html
file_upload.html

3 ajax上传json格式

urlpatterns = [
 
    url(r'^ajax_json/', views.ajax_json),
 
]
urls.py
def ajax_json(request):
    import json
    if request.method == 'GET':
        return render(request,'ajax_json.html')

    else:
        # json格式,从POST中取不出来
        name = request.POST.get('name')
        print(type(request.POST)) # 实际上不是一个真正的字典格式
        # from  django.http.request import QueryDict
        print(name)
        # 在body体中,b格式
        request.data = json.loads(request.body)

        name = request.data.get('name')  # 拿到用户名
        password = request.data.get('password') # 拿到密码 
        print(name)
        print(password)
        return HttpResponse('ok')

views.py
views.py

"en">

    "UTF-8">
    Title
    



ajax提交json格式

用户名: "text" id="id_name">

密码: "password" id="id_password">

ajax_json.html
ajax_json.html

使用ajax上传json格式数据,写一个装饰器,实现不论前端以什么格式传递数据,我从视图函数中都从request.data中取值(POST的数据)

urlpatterns = [
    url(r'^test_json/', views.test_json),

]
urls.py
from django.shortcuts import render, redirect, HttpResponse
from django.http import JsonResponse

from app01 import models
import json


def json_paser(func):
    def inner(request, *args, **kwargs):
        if request.method == 'POST':
            try:
                """
              只有post请求才有这种情况,get请求就不用管了
              直接去loads.body,如果body里面是json格式,毫无疑问就有值了
              能够loads到就只有一种情况就是通过json格式传过来的,其它两种
              情况就会抛异常
                """
                request.data = json.loads(request.body)
            except Exception as e:
                request.data = request.POST

        res = func(request, *args, **kwargs)
        return res

    return inner


@json_paser
def test_json(request):
    if request.method == 'GET':
        return render(request, 'test_json.html')
    else:
        print(request.data)
        return HttpResponse('ok')
        # return render(request,'book_page.html') # 返回的是一个纯的html页面
        # return redirect('http://www.baidu.com') # 直接报错

views.py
views.py

"en">

    "UTF-8">
    Title
    
    "https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    








test_json
test_json

补充知识

json.loads(b'dfdasfda')
问题:json可以直接loads bytes格式吗?
  -3.5之前不可以
  -3.6以后可以

Django内置的serializers(把对象序列化成json字符串)(了解)

把对象转成json格式字符串,返回给前端,django内置的不好用,字段不能控制

目前阶段,要做序列化,for循环拼列表套字典

from django.core import serializers
urlpatterns = [
    url(r'^test/', views.test),
]
urls.py
def test(request):
    user_list = models.User.objects.all()
    ret = serializers.serialize("json", user_list)

    return HttpResponse(ret)
views.py
class User(models.Model):
    name=models.CharField(max_length=32)
    password=models.CharField(max_length=32)
models.py