Django基础之Ajax

Django基础之Ajax

一.简介

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即 使用Javascript语言与服务器进行数据的异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 的..特点..

1.在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。提升用户体验感

2.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求/

 

例子:局部刷新

HTML部分:

<body>
​
    {% csrf_token %}
    用户名:<input type="text" name="username" id="username"><br>
    密码:    <input type="password" name="password" id="password"><br>
    <input type="button" value="提交" id="tj"><span id="dang"></span>
​
​
</body>
<script src="{% static '/jquery/jquery-3.4.1.js' %}"></script><script>
    $("#tj").click(function () {
        var username=$('#username').val();          #获取用户输入的内容
        var password=$('#password').val();
        var csrf_data=$('[name=csrfmiddlewaretoken]').val();    #获取csrf机制为网页提供的值
        $.ajax({                #ajax格式,向服务器提交数据
​
            url:"{% url 'login' %}",            #指定提交的路径
            type:'post',                        #指定获取的方式
            data:{                              
                username:username,              #data 将获取数据提交
                password:password,
                csrfmiddlewaretoken:csrf_data
            },
            success:function (response) {        #提交成功后,response获得返回值
​
                if(response==='abc123'){
                    alert('ok')
                }else{
                    $('#dang').text('输入的内容有误!')
                }
            }
        })
    })
​
</script>

views视图部分:
def login(request):
    if request.method=='GET':
        return  render(request,'login.html')
    else:
        username=request.POST.get('username')
        password=request.POST.get('password')
        print(username,password)
​
        return HttpResponse([username,password])
        
     
urls部分:
from app01 import views
​
urlpatterns = [
​
    url(r'^login/', views.login,name='login'),
]
 

二.上传文件

通过form表单上传文件
HTML界面:
    <form action="" method="post" enctype="multipart/form-data">  #enctype这个属性必须填写,才能实现文件的上传
        {% csrf_token %}
        用户名:<input type="text" name="username" id="username"><br>
        密码:    <input type="password" name="password" id="password"><br>
        文件上传:<input type="file" name="unload">
        <input type="submit">
    </form>

views视图:
    def login(request):
    if request.method=='GET':
        return  render(request,'login.html')
​
    else:
        files = request.FILES.get('unload')         #获取上传的文件
        print(files)
        files_path = os.path.join(settings.BASE_DIR,'jingtai','img',files.name) #拼接路径
        with open(files_path,'wb') as f:
            for data in files:   
                f.write(data)     #将文件的内容写入指定路径
return HttpResponse('ok')

 


基于ajax
HTML方面:

<form>
    {% csrf_token %}
    用户名:<input type="text" name="username" id="uuu"><br>
    密码:    <input type="password" name="password" id="ppp"><br>
    文件上传:<input type="file" name="unload">
    <input type="button" value="提交" id="tj">
</form>
​
​
</body>
<script src="{% static 'jquery-3.4.1.js' %}"></script><script>
    $('#tj').click(function () {
        var formdata=new FormData();                #new方法获取一个formdata对象,必须有,因为只有将文件内容放到这个对象里,才能实现文件上传
        var username=$('[name=username]').val();
        var password=$('[name=password]').val();
        var file_obj=$('[name=unload]')[0].files[0];
        var csrf_data=$('[name=csrfmiddlewaretoken]').val();   #获取csrf值
        formdata.append('username',username);
        formdata.append('password',password);
        formdata.append('file_obj',file_obj);
        formdata.append('csrfmiddlewaretoken',csrf_data);
​
        $.ajax({
            url:'{% url 'unload' %}',
            type:'post',
            data:formdata,
            processData:false,      #--->
            contentType:false,      #--->如果通过ajax上传文件,这两条必须写
            success:function (res) {
                console.log(res);
            }
​
        })
​
    })
​
​
</script>

 




views视图方面:
    from testAjax import settings    #导入项目文件中的settings文件
    def unload(request):
​
        if request.method=='POST':
            files=request.FILES.get('file_obj')         #获取上传的文件信息
            print(files)
            files_path = os.path.join(settings.BASE_DIR,'jingtai','img',files.name)
                            #拼接路径
            with open(files_path,'wb') as f:
                for data in files:
                    f.write(data)    #读取上传文件信息,并写入指定路径
return HttpResponse('ok')
​
        else:
            return render(request,'unload.html')

       
基于ajax,利用cookie
body部分也不用书写{% csrf-token %},也不用获取它的值,,直接在ajax中输入下面的指令就行
$.ajax({
            url:'{% url 'unload' %}',
            type:'post',
            data:formdata,
            headers:{'X-CSRFToken':$.cookie('csrftoken')},    #导入cookie,直接加入这条命令
            processData:false,
            contentType:false,
            success:function (res) {
                console.log(res);
            }
​
        })

 



contentType的三种类型

contentType,请求体的编码类型,常见有3种类型

1.application/x-www-form-urlencoded

常见的post提交数据方式,在form表单中,如果不设置'enctype'属性,就默认为该方式提交数据,ajax也默认这个.

请求类似于下面这样:

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

user=yuan&age=2   #这个结果就是上面这种Content-Type规定的数据格式,后端对应这个格式来解析获取数据
2.multipart/form-data

常见的数据提交方式.在使用form表单上传文件的时候,需要将enctype属性设置成 multipart/form-data

,注意form表单不支持发送json类型的contenttype格式的数据,这也是ajax应用广泛的原因之一.

例子上面就有:form表单上传文件

 

3.application/json

例子:

HTML界面:

<body>
    {% csrf_token %}
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <button id="tj">提交</button></body>
<script src="{% static 'jquery-3.4.1.js' %}"></script><script>
    $('#tj').click(function () {
        var username=$('[name=username]').val();
        var password=$('[name=password]').val();
        $.ajax({
            url:'{% url 'home2' %}',
            type:'post',
            headers:{
​
                'Content-Type':'application/json'  
                                            #将请求体的编码类型设置为'application/json'
            },
            data:JSON.stringify({
                username:username,      #对数据处理,转换成字符串类型,然后发给后端
                password:password
            }),
            success:function (res) {
​
                {#通过JsonResponse传送过来的数据,#}
                console.log(res);
                console.log(typeof res);
                console.log(res.username);
                console.log(res.password);
​
                    
                {#实现页面的跳转#}    
                console.log(res);
                var url=res.url;
                location.href=url   
​
            }
        })
​
    })
​
</script>

       

VIEWS视图:

# json实现数据的传送请求
import json
from django.http import JsonResponse
​
def home(request):
    return render(request,'home.html')
​
def home2(request):
    # 1.通过数据说明django中没有json解释器
    print(request.body)         #b'{"username":"\xe5\xb0\x8f\xe7\x99\xbd","password":"111"}'
print(request.GET)          #<QueryDict: {}>     因为django中没有json的解释器,所以从前端接收到的数据无法解析
    print(request.POST)         #<QueryDict: {}>     所以GET,POST不到数据,只能从最原始的数据body里面查找.
return HttpResponse('ok')
​
​
    l=[1,2,3]
​
    return  HttpResponse(l,content_type='application/json')
​
​
    #2. 通过JsonResponse传输字典类型
    res=request.body.decode('utf-8')
    print(res,type(res))
    res_str=json.loads(res)
    print(res_str)
    return  JsonResponse(res_str)     #JsonResponse的作用,将传入的字典数据返还给前端,自动变成JSON的对象,不需要再经过parse的转换过程
                                #后面的数据必须是字典形式
#3.通过JsonResponse传输非字典类型
    res = request.body.decode('utf-8')
    print(res, type(res))
    return  JsonResponse(res,safe=False)
                                #如果不是的话,需要加上safe=Flase,则传送的是什么数据,前端那块接受的就是什么数据,不会对其进行处理.
#4. 页面跳转
    res = request.body.decode('utf-8')
    res_dic = json.loads(res)
    res_obj=       {'username':res_dic['username'],'password':res_dic['password'],'url':'/login/'} #将从前端获取的数据进行处理并发送
    return JsonResponse(res_obj)

 

 

补充知识点:

#因为时间对象JSON无法对其进行转换,通过以下方法可以实现将其转换成字符串然后再进行序列化

import json
from datetime import datetime,date
a = {'name':'chao','timer':datetime.now()}
​
​
class JsonCustomEncoder(json.JSONEncoder):
    def default(self, field):
        if isinstance(field,datetime):
            return field.strftime('%Y-%m-%d %H:%M:%S')    #该方法将a里面的datatime.now()对象变成字符串那类型,以方便json进行序列化.
        elif isinstance(field,date):
            return field.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self,field)
​
a_json = json.dumps(a,cls=JsonCustomEncoder)
print(a_json)

 


 

posted @ 2019-08-14 18:36  socoolonly1  阅读(132)  评论(0编辑  收藏  举报