AJAX of Django

Posted by millwardt on Fri, 10 Jan 2020 14:48:46 +0100

Catalog

AJAX introduction

AJAX (Asynchronous Javascript And XML) is translated into Chinese as "Asynchronous Javascript And XML". That is to say, Javascript language is used to interact with the server asynchronously, and the data transmitted is XML (of course, the data transmitted is not only XML).

AJAX is not a new programming language, but a new way to use existing standards. In fact, it's just a function module written based on js

Because the writing of ajax in native js is complicated, we can directly learn the ajax module operation of jQuery package number

The biggest advantage of AJAX is: asynchronous submission, local refresh

    Without reloading the entire page, you can exchange data with the server and update part of the page content. (this feature gives users the feeling of completing the request and response process unconsciously.)

AJAX doesn't require any browser plug-ins, but it requires the user to allow JavaScript to execute on the browser.

Synchronous interaction: after the task is submitted, the process waiting for the return result of the task is blocked
 Asynchronous interaction: after the task is submitted, you don't need to wait for the return result in place to execute the next line of code directly. The process is non blocking
        The result of the task is called back ()

Case: the user name interacts with the backend at all times, but the page is not refreshed. Better user experience

The interaction between the front end and the back end is as follows:

1. Enter url in browser window and enter GET
 2. Fill in the url of the a tag's href attribute and click GET
 3.form form GET/POST
4.Ajax                                    GET/POST

AJAX basic syntax structure

Small case:

First acquaintance with ajax
    Case: there are three input boxes and one button on the page
    Users input numbers in the first two boxes and click the button to ensure that the data will be sent to the back-end for calculation without refreshing the page
    Send the calculated results to the front end and display them in the third input box

Effect:

def index(request):
    if request.method == 'POST':
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        # i1 and i2 are string types. Type conversion is required first
        i3 = int(i1) + int(i2)
        return HttpResponse(i3)
    return render(request,'index.html')
ajax Basic grammatical structure
        // ajax basic syntax
        $.ajax({
                    // 1. Which backend to submit data to
            url:'',  // There are three ways to write the submission path of control data, which are consistent with the action attribute of form form form
            type:'post',  // 2. Specify the current request method
            data:{'i1':$('#i1').val(),'i2':$('#I2 '). Val()}, / / 3. Submitted data
                        // 4.ajax is submitted asynchronously, so you need to give a callback function to handle the returned results
            success:function (data) {  // data is the return result of asynchronous submission
                // Render the result of the asynchronous callback to the third input box through DOM operation
                $('#i3').val(data)
            }
        })

Data encoding format of front and back end interaction

urlencoded
formdata
application/json

Form form

Form form is urlencoded by default to transmit data
 urlencoded data format:
    username=jason&password=123
    django backend will automatically parse and package the data in this format into request.POST

formdata data format:
    Whether the django backend uniformly parses the urlencoded data (common key value pairs) into request.POST
    The data of formdata file will be automatically parsed and put into request.FILES
    
application/json
    django backend does not do any processing for json format data
    It's directly in request.body

ajax submission

ajax is also urlencoded by default
    The coding format of front and back data interaction must be consistent with that of data format
    You can't cheat others!!!, you can use whatever encoding format you declare
            $('#d2').on('click',function () {
                $.ajax({
                    url:'',
                    type:'post',
                    contentType:'application/json',  // Modify content type parameter
                    data:JSON.stringify({'username':'jason','password':123}),  // Sequence data into json format string
                    success:function (data) {
                        alert(data)
                    }
                })
            })

How to get json data from the backend?

The front-end does not process the data in json format, but directly inserts it into request.body. We handle json format data by ourselves, and we get binary json

How can we take it ourselves?

We process, decode, deserialize ourselves

json.loads can decode and serialize automatically

def ab_ct(request):
    if request.method == 'POST':
        # Handle json format data by yourself
        json_bytes = request.body
        # Extension json.loads can automatically decode and sequence
        json_dict = json.loads(json_bytes)
        print(json_dict,type(json_dict))
        print(request.POST)
        print(request.FILES)
    return render(request,'ab_ct.html')

AJAX send file

Need to use the built-in object FormData

This object can be transferred to normal key value pairs or files

jQ new keyword generation object

    ajax send files(******)
        //Built in object FormData
        //Send common key value pairs as well as files
        // ajax needs built-in objects to send file data
        $('#d3').click(function () {
            // 1 need to build a built-in object
            var myFormData = new FormData();
            // 2. When there are many common key value pairs, we can use for loop to add
            myFormData.append('username','jason');
            myFormData.append('password',123);
            // 3 document transmission
            myFormData.append('myfile',$('#i1')[0].files[0]; / / get the file object uploaded by the internal user of the input box
            // Send ajax request
            $.ajax({
                url:'',
                type:'post',
                data:myFormData,
                // Two key parameters need to be specified to send the formdata object

                processData:false,  // Let the browser do nothing with your data
                contentType:false,  // Do not use any encoding format object formdata has its own encoding format and django can recognize the object

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

Automatic serialization

Help you automate serialization with serializers

from app01 import models
from django.core import serializers
def ab_se(request):
    user_queryset = models.Userinfo.objects.all()
    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)
    res = serializers.serialize('json',user_queryset)  # serialize
    return HttpResponse(res)

Pager application

All you need to know is how to use it
    //The derivation idea can be understood a little
    //back-end
        current_page = request.GET.get('page', 1)
        all_count = book_queryset.count()
        # 1 now generate a custom pager class object
        page_obj = Pagination(current_page=current_page,all_count=all_count,pager_count=9)
        # 2 slice the real queryset data
        page_queryset = book_queryset[page_obj.start:page_obj.end]
        return render(request,'ab_bc.html',locals())

    //Front end  
        {% for book_obj in page_queryset %}
            <p>{{ book_obj.title }}</p>
        {% endfor %}
        {{ page_obj.page_html|safe }}

CV grand law

class Pagination(object):
    def __init__(self,current_page,all_count,per_page_num=2,pager_count=11):
        """
        //Encapsulate paging related data
        :param current_page: Current page
        :param all_count:    Total number of data in the database
        :param per_page_num: Number of data displayed per page
        :param pager_count:  Maximum number of pages displayed
        
        //Usage:
        queryset = model.objects.all()
        page_obj = Pagination(current_page,all_count)
        page_data = queryset[page_obj.start:page_obj.end]
        //Get data with page ﹣ data instead of the original queryset
        //To get the front-end page style, use 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


        # Total page number
        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):
        # If the total page number is less than 11:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # Total page > 11
        else:
            # If the current page is < = at most 11 / 2 pages are displayed on the page
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # Current page is greater than 5
            else:
                # Page to the end
                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 = []
        # Add previous nav and ul Tags
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">home page</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#"> previous page
        else:
            prev_page = '<li><a href="?page=%s">Previous page</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="#"> next page
        else:
            next_page = '<li><a href="?page=%s">next page</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">Tail page</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # Tag tail
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)

Topics: Python JSON encoding Django Javascript