django and ajax, pager, bulk insert data

1. What is ajax

ajax stands for asynchronous JavaScript and XML or HTML (subset of the Standard Generalized Markup Language, is a component in JavaScript or a kind of technology is its greatest feature: the back-end without refreshing the entire page for information exchange. the so-called asynchronous submission, partial refresh, which makes ajax good performance.

Added: asynchronous submit the results can be returned () callback function to be performed by a callback.

Several front-end access back-end way:

与后端进行交互的方式
1.浏览器窗口输入url回车                    GET
2.a标签href属性填写url点击                 GET
3.form表单                               GET/POST
4.Ajax                                   GET/POST

Note that the submission of data form the way the form will refresh the entire page, which in many cases is not appropriate, such as when the user is filling out the registration information and submit, after the back-end verification found that user name already exists, it should be returns information registration failure, then if the form is submitted form, fill in the user data will be lost, so ajax is a better choice.

The basic syntax of 2.ajax

$.ajax({
    url:'',      # 发送请求的url,不写默认为当前url
    type:'post', # get或post请求
    data:{'username':'kiki','password':123} # data以自定义对象的方式
    success:function (data){
        # data为后端返回的数据
        # 回调函数
    }
})

3. The front end of the interactive format encoding

content-Type:前后端传输数据的编码格式
    urlencoded
    formdata
    application/json

urlencoded is form form data and the default encoding format ajax, django rear end will meet this encoding format data to automatically parse and packaged in request.POST. When our form form has a file, the file name will be submitted, while the real file data is not sent.

username=syyanyuhui&password=123&file=QQ%E5%9B%BE%E7%89%8720200106165917.bmp

formdata encoding format may be submitted together with the rear end of the data file, it will meet Django urlencoded encoded data to automatically resolve Medicine request.POST rather satisfying formdata file data in the parsed into request.FILES.

application/json

# ajax默认的是urlencoded编码格式
# 前后端数据交互 编码格式与数据格式一定要一致

# application/json
# django后端针对json格式数据 并不会做任何的处理而是直接放在request.body中

$('#d2').on('click',function () {
    $.ajax({
        url:'',
        type:'post',
        ######### 修改content-Type参数 #####################
        contentType:'application/json',
        data:JSON.stringify({'username':'jason','password':123}),  # 将数据序列化成json格式字符串
        success:function (data) {
            alert(data)
        }
    })
})

4. Send file ajax

When using ajax to send the file, need the help of built-in objects formdata, formdata object can be passed in both normal key-value pairs, you can also pass a file object. Need to set two crucial parameters. processData and contentType . At the same time can not be specified encoding format, formdata own encoding format.

$('#d3').click(function () {
    # 初始化formdata对象
    var myFormData = new FormData();
    # 普通键值对
    myFormData.append('username','jason');
    myFormData.append('password',123);
    # 添加文件对象
    myFormData.append('myfile',$('#i1')[0].files[0]);  // 获取input框内部用户上传的文件对象
    
    $.ajax({
        url:'',
        type:'post',
        data:myFormData,
        
        processData:false,  # 浏览器不要对数据进行任何的操作
        contentType:false,  

        success:function (data) {
            alert(data)
        }
    })
})

5.django built serialization module

from django.core import serializers
# serializers可以将queryset对象序列化成json数据格式,可以非常方便的进行序列化。(json不能直接序列化queryset对象)
def test(request):    
    user_queryset = models.Userinfo.objects.all()
    res = serializers.serialize('json',user_queryset
    return HttpResponse(res)
# 不采用模块的方式
'''
    user_list = []
    for user_obj in user_queryset:
        user_list.append({
            'username':user_obj.username,
            'password':user_obj.password,
            'gender':user_obj.get_gender_display(),
        })
    res = json.dumps(user_list)
'''

6.django bulk insert data

When we want to insert data orm bulk, directly create efficiency is very low, each execution of the statement had to create a database connection.

django provides bulk_create method for us.

# 先创建一个空列表,然后创建记录对象保存在列表中,最后用bulk_create方法一起插入数据库中。
book_list = []
for i in range(10000):
    book_list.append(models.Book(title=f'第{i}本书'))
models.Book.objects.bulk_create(book_list)

7. Customizing finisher

Incoming current page, the total number of data per page shows the number of pieces of data, the number of paging buttons

Call page_html () method, the front end of the page {{pagination | safe}}

import math
class Pagination(object):
    def __init__(self,current_page,all_count,per_page_num=2,pager_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数
        
        用法:
        queryset = model.objects.all()
        page_obj = Pagination(current_page,all_count)
        page_data = queryset[page_obj.start:page_obj.end]
        获取数据用page_data而不再使用原始的queryset
        获取前端分页样式用page_obj.page_html
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page <1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num


        # 总页码
        all_pager = math.ceil(all_count/per_page_num)
#        all_pager, tmp = divmod(all_count, per_page_num)
#        if tmp:
#            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)
# 后端代码
def show_book(request):
    cur_page = request.GET.get('page')
    try:
        cur_page = int(cur_page)
    except Exception:
        cur_page = 1
    # 每页显示记录条数
    count_per_page = 2
    start_index = (cur_page-1) * count_per_page
    stop_index = start_index + count_per_page
    # 记录总条数
    book_queryset = models.Book.objects.filter()
    total_count = book_queryset.count()

    pagination = Pagination(cur_page, total_count,count_per_page)
    # 要被显示的记录
    book_queryset = book_queryset[start_index:stop_index]
    return render(request, 'book.html', locals())

django backend save the file objects in two ways

# 方式1:
def upload(request):
    print("request.GET:", request.GET)
    print("request.POST:", request.POST)

    if request.FILES:
        filename = request.FILES["file"].name
        with open(filename, 'wb') as f:
            for chunk in request.FILES['file'].chunks():
                f.write(chunk)
# 方式2:
def index(request):
    if request.method == 'GET':
        return render(request, 'index.html')
    print(request.POST)
    file = request.FILES.get('file')
    default_storage.save(file.name,ContentFile(file.read()))
    return render(request, 'index.html')

Guess you like

Origin www.cnblogs.com/Ghostant/p/12177892.html