博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Django与ajax,django内置序列化serializers

Posted on 2022-03-11 23:00  ~sang  阅读(94)  评论(0编辑  收藏  举报

Django与ajax

ajax翻译成中文就是"异步的javascript和XML"。即使用javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)
ajax最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
同步交互:客户端发出一个请求后,需要等待服务器响应结束,才能发出第二个请求
   异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求
# ajax的优点
ajax使用javascript技术向服务器发送异步请求;
ajax请求无需刷新整个页面;
因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以ajax性能高;
两个关键点:
1.局部刷新:js的dom操作,使页面局部刷新
   2.异步请求
   
$.ajax({
   url:'/index/',  # ajax请求的地址,不写就是向当前路径提交
   method:'post/get',  # 请求方式
   //contentType:'application/json'  //指定编码格式,json格式
   # 上传文件,一定要注意如下两行
   //processData:false,  //不预处理数据
   //contentType:false,  //不指定编码格式,使用formdata对象的默认编码就是formdata格式
   data:json格式字符串,字典对象,formdata对象  # 携带参数
   success:function(data){
       //data的类型取决于后端返回时指定的响应类型
      ...
  }
})

ajax与后端交互

# 后端
def ajax_test(request):
       return render(request,'ajax_test.html')

   def two_sum(request):
       import time
       time.sleep(2)
       a1=int(request.GET.get('a1'))
       a2=int(request.GET.get('a2'))
       return HttpResponse(a1+a2)
# 前端
<body>
   <input type="text" id="a1">+<input type="text" id="a2">=<input type="text" id="two_sum">
   <button id="btn_submit">计算</button>

   <script>
       $('#btn_submit').click(function (){
           var a1=$('#a1').val()
           var a2=$('#a2').val()
           // 发送ajax请求,计算,返回结果
           $.ajax({
               url:'/two_sum/',  // ajax请求的地址,不写就是向当前路径提交
               method:'get',  // 请求方式
               data:{'a1':a1,'a2':a2},  //携带参数
               success:function (data){  //服务端成功返回会回调,执行匿名函数
                   console.log(data)
                   $('#two_sum').val(data)
              }
          })
      })
   </script>
   </body>

ajax发送其它请求(注意)

1.如果在form表单中,写button和input是submit类型,会触发form表单的提交
 如果不想触发:
     -不写在form表单中
     -使用input,类型是button
2.后端响应格式如果是:html/text格式,ajax接收到数据后需要自己转成对象
 后端响应格式是:json,ajax接收到数据后会自动转成对象
 总结:后端返回数据,统一都用JsonResponse
3.如果使用了ajax,后端就不要返回redirect,render,HttpResponse
 直接返回JsonResponse
# javascript中关于json对象和字符串转换的两个方法
JSON.parse():用于将一个JSON字符串转换为javascript对象(json只认双引的字符串格式)
   JSON.parse('{"name":"HowKer"}');
JSON.stringify():用于将javascript值转换为JSON字符串
   JSON.stringify({"name":"Tonny"})
# data参数中的键值对,如果值不为字符串,需要将其转换成字符串类型
data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])},
# JsonResponse是HttpResponse的子类,适用于处理json格式的数据,但是不能返回模板。帮助我们将数据转换为json字符串,设置响应头Content-Type为application/json

登录功能验证

# 后端
from django.shortcuts import render,redirect,HttpResponse,reverse
   from django.http import JsonResponse
   from app01 import models
   def login(request):
       if request.method=='GET':
           return render(request,'login.html')
       # elif request.method=='POST':
       elif request.is_ajax():
           response={'status':100,'msg':None}
           name=request.POST.get('username')
           password=request.POST.get('password')
           user=models.User.objects.filter(username=name,password=password).first()
           if user:
               # return redirect('') 出错
               response['msg']="登录成功"
           else:
               response['status']=101
               response['msg']="用户名或密码错误!"
           return JsonResponse(response)
# 前端
<body>
   <p>用户名:<input type="text" id="id_name"></p>
   <p>密码:<input type="password" id="id_password"></p>
   <button id="id_btn">提交</button> <span class="error" style="color: red"></span>

   <script>
       $('#id_btn').click(function (){
           $.ajax({
               url:'/login/',
               method:'post',
               data:{username:$('#id_name').val(),password:$('#id_password').val()},
               success:function (data){
                   //data现在是对象类型
                   if(data.status==100){
                       //登录成功,重定向到百度,前端重定向
                       location.href='http://www.baidu.com'
                       //location.href='/index/'
                  }else{
                       //登录失败
                      {#$('.error').html(data.msg).css({'color':'red'})#}
                       $('.error').html(data.msg)
                  }
              },
               error:function (data){
                   console.log(data)
              }
          })
      })
   </script>
   </body>

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

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

form表单上传文件

# 后端
def form_file(request):
       if request.method=='POST':
           myfile=request.FILES.get('myfile')
           print(myfile.name)  # 打印文件名称
           with open(myfile.name,'wb') as f:
               for line in myfile:
                   f.write(line)
       return render(request,'form_file.html')
# 前端
<body>
   <h1>form表单上传文件</h1>
   <hr>
   <form action="" method="post" enctype="multipart/form-data">
       <p>用户名:<input type="text" name="file_name"></p>
       <p>文件:<input type="file" name="myfile"></p>
       <input type="submit" value="提交">
   </form>
   </body>

ajax上传文件

# 后端
def file_upload(request):
       if request.method=='POST':
           name=request.POST.get('name')
           print(name)
           myfile=request.FILES.get('myfile')
           print(type(myfile))  # 查看类型
           # from django.core.files.uploadedfile import InMemoryUploadedFile
           with open(myfile.name,'wb') as f:
               for line in myfile:
                   f.write(line)
           return HttpResponse('上传成功')
       return render(request,'file_upload.html')
# 前端
<body>
   <h1>ajax上传文件</h1>
   <hr>
   <p>用户名:<input type="text" id="id_name"></p>
   <p>文件:<input type="file" id="id_myfile"></p>
   <button id="id_btn">提交</button>

   <script>
       $('#id_btn').click(function (){
           //如果要上传文件,需要借助于一个js的FormData对象
           var formdata=new FormData()  //实例化得到一个FormData对象
           formdata.append('name',$('#id_name').val())  //追加了一个name对应填入的值
           //能追加文件
           var file=$('#id_myfile')[0].files[0]
           formdata.append('myfile',file)
           $.ajax({
               url:'/file_upload/',  //ajax请求的地址
               method:'post',
               //上传文件,一定要注意如下两行
               processData:false,  //不预处理数据
               contentType:false,  //不指定编码格式,使用formdata对象的默认编码就是formdata格式
               data:formdata,
               success:function (data){
                   alert(data)
              }
          })
      })
   </script>
   </body>

ajax上传json格式

# 提交json格式,后端无论是什么格式,都从request.data中取值
# request.data=json.loads(request.body)
# 后端
import json
   def ajax_json(request):
       if request.method=='POST':
           # json格式,从POST中取不出来
           name=request.POST.get('name')  # None
           print(type(request.POST))
           print(name)
           # 从body体中取
           request.data=json.loads(request.body)
           name=request.data.get('name')
           password=request.data.get('password')
           print(name)
           print(password)
           return HttpResponse('ok')
       return render(request,'ajax_json.html')
# 前端
<body>
   <h1>ajax上传json格式</h1>
   <hr>
   <p>用户名:<input type="text" id="id_name"></p>
   <p>密码:<input type="password" id="id_password"></p>
   <button id="id_btn">提交</button>
   <script>
       $('#id_btn').click(function (){
           $.ajax({
               url:'/ajax_json/',
               method:'post',
               contentType:'application/json',  //指定编码格式
               data:JSON.stringify({name:$('#id_name').val(),password:$('#id_password').val()}),  //json格式字符串
               success:function (data){
                   console.log(data)
              }
          })
      })
   </script>
   </body>

django内置序列化serializers

'''
什么意思呢?就是我的前端想拿到由ORM得到的数据库里面的一个个用户对象,我的后端想直接将实例化出来的数据对象直接发送给客户端,那么这个时候,就可以用django给我们提供的序列化方式
把对象转成json格式的字符串,django内置的不好用,字段不能控制
目前阶段,要做序列化,for循环拼列表套字典
'''

from django.core import serializers
def ser(request):
   user_list=models.User.objects.all()
   ret=serializers.serialize("json",user_list)
   return HttpResponse(ret)
# 返回结果
[{"model": "app01.user", "pk": 1, "fields": {"username": "ldb", "password": "123"}}, {"model": "app01.user", "pk": 2, "fields": {"username": "marry", "password": "222"}}, {"model": "app01.user", "pk": 3, "fields": {"username": "\u5f20\u4e09", "password": "666"}}]