Django学习——ajax发送其他请求、上传文件(ajax和form两种方式)、ajax上传json格式、 Django内置序列化(了解)、分页器的使用


1 ajax发送其他请求

1 写在form表单 submit和button会触发提交  
注释 2 使用input 类型为 button 1 大坑 -如果在form表单中,写button和input是submit类型,会触发form表单的提交 -如果不想触发: -不写在form表单中 -使用input,类型是button

用户名:

密码:

{# #}
// 登录成功,重定向百度,前端重定向 location.href='http://www.baidu.com' location.href='/index/' 2 坑 -后端响应格式如果是:html/text格式,ajax接收到数据后需要自己转成对象 res = JSON.parse(data) // 不是json格式需要手动解析 -后端响应格式是:json,ajax接收到数据后会自动转成对象 -总结:后端返回数据,统一都用JsonResponse 3 坑 -如果使用了ajax,后端就不要返回rediret,render,HttpResponse -直接返回JsonResponse

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

默认请求编码格斯为:urlencoded 上传文件需要使用格式:enctype="multipart/form-data"
1 http --post--请求,有编码格式,主流有三种
	-urlencode:默认的  ----> 从request.POST取提交的数据
	-form-data:上传文件的  ----> 从request.POST取提交的数据,request.FILES中取文件
	-json:ajax发送json格式数据  ----> 从request.POST取不出数据
    
2 使用ajax和form表单,默认都是urlencode格式
3 如果上传文件:form表单格式  enctype=
4 如果编码方式是urlencode格式,放到body体(请求体)中数据格式如下: ajax预处理数据
	username=lqz&password=123
    

form表单上传文件

用户名:

文件:

ajax上传文件

用户名:

文件:

$('#id_myfile')[0] # jQuery对象转成原生input $('#id_myfile')[0].files # 所有的文件 $('#id_myfile')[0].files[0] # js中的文件对象 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)) # 查看类型 from django.core.files.uploadedfile import InMemoryUploadedFile with open(myfile.name,'wb') as f: for line in myfile: f.write(line) return HttpResponse('上传成功') 2.1 form表单上传文件 2.2 ajax上传文件 2.3 后端 2.4 路由

3 ajax上传json格式

3.1 前端




    
    Title
    
    {#    #}
    {#    #}



ajax提交json格式

用户名:

密码:

3.2 后端

def ajax_json(request):
    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')

4 Django内置序列化(了解)

Django内置的serializers(把对象序列化成json字符串)
from django.core import serializers
from django.core import serializers
def test(request):
    book_list = Book.objects.all()    
    ret = serializers.serialize("json", book_list)
    return HttpResponse(ret)

把对象转成json格式字符串,Django内置的不好用,字段不能控制
目前阶段,要做序列化,for循环拼列表套字典

l = []
for user in user_list:
    l.append({'name':user.name,'password':user.password})
return JsonResponse(l,safe=False)

5 分页器的使用

###  批量插入数据
def books_page(request):
    # 第一种方案,每循环一次,操作一下数据库,性能低
    # for i in range(1000):
    #     book= models.Books.objects.create(name='图书%s' % i, price=i+10, publish='东京出版社')

    # 第二种方案,批量插入
    book_list = []
    for i in range(1000):
        book = models.Books(name='图书%s' % i, price=i+10, publish='东京出版社')
        book_list.append(book)

    models.Books.objects.bulk_create(book_list,batch_size=100)
    return HttpResponse('ok')


1 Django的分页器(paginator)简介
在页面显示分页数据,需要用到Django分页器组件

from django.core.paginator import Paginator

Paginator对象:    paginator = Paginator(user_list, 10)
# per_page: 每页显示条目数量
# count:    数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page:     page对象    
page对象:page=paginator.page(1)
# has_next              是否有下一页
# next_page_number      下一页页码
# has_previous          是否有上一页
# previous_page_number  上一页页码
# object_list           分页之后的数据列表
# number                当前页
# paginator             paginator对象

from django.core.paginator import Paginator
# def books_page(request):
#     current_num = int(request.GET.get('page_num',1))  # 如果请求不到当前页 返回第一页
#     book_list= models.Books.objects.all()
#     paginator=Paginator(book_list,50)
#     # Paginator对象的属性
#     print(paginator.count)  # 数据总条数
#     print(paginator.num_pages)  # 总页数
#     print(paginator.per_page)  # 每页显示条目数量
#     print(paginator.page_range)  # 总页数的索引范围 range(1, 101)
#     # print(paginator.page(1))  # 第一页
#     # page对象的属性和方法
#     # has_next              是否有下一页
#     # next_page_number      下一页页码
#     # has_previous          是否有上一页
#     # previous_page_number  上一页页码
#     # object_list           分页之后的数据列表
#     # number                当前页
#     page = paginator.page(current_num)
#     print(page.has_next())
#     print(page.next_page_number())
#     print(page.has_previous())
#     print(page.previous_page_number())
#     print(page.object_list)
#     print(page.number)
#
#     return render(request,'book_page.html',locals())

def books_page(request):
    current_num = int(request.GET.get('page_num',1))
    book_list= models.Books.objects.all()

    paginator=Paginator(book_list,50)
    page = paginator.page(current_num)
    return render(request,'book_page.html',locals())

练习

1 使用ajax发送post请求,完成注册功能,注册成功,跳转到登录,登录成功跳转到百度

2 使用ajax上传文件,保存到项目路径的media路径下(登录成功才能上传文件)

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

def json_parser(func):
    def inner(request,*args,**kwargs):
        if request.method == 'POST':
            try:
                request.data=json.loads(request.body)  # json格式
            except Exception as e:
                request.data=request.POST  # 其他两种格式
        res = func(request,*args,**kwargs)
        return res
    return inner


@json_parser
def test_json(request):
    if request.method == 'GET':
        return render(request,'test_json.html')
    else:
        print(request.data)
        return HttpResponse('ok')

补充

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

回顾

1 ajax
	$.ajax({
        url:'/test/',
        method:'get/post',
        contentType:'application/json',
        //processData:false,
        //contentType:false,
        data:json格式字符串,字典对象,formdata对象,
        success:function(){
            //data的类型取决于,后端返回时指定的响应类型
            ...
        }
    })
        
2 上传文件(form表单,ajax)
3 提交json格式,后端无论是什么格式
4 登录注册功能