Django and jQuery implement Ajax table data pagination display

1. Requirement description

When there is a function that re-requests the interface to return data, if the content of the page is very long, every time a function is clicked, the page returns to the top, which is not very friendly to the user experience. We hope that when the user clicks on such a function , can be loaded directly into the data, and the operations requested by the backend will not be displayed on the frontend, giving the user an imperceptible state.

If you want to dynamically obtain the data of a certain function point without reloading the page, you need to use Ajax technology. When the button of a certain function is clicked, an Ajax request is triggered, and Ajax interacts with the backend (Django). , after passing some parameters to get new data, it is finally rendered on the front-end page.

There is a problem that needs to be considered: the paging buttons on the front end have styles, and the styles are judged based on the parameters returned by the back end, and the final decision is made to which paging button to add styles. In order to avoid paging data, the paging data can be obtained normally, but the paging style is not Will change. Thinking based on this problem, the final solution is: also render the paging part of the code through Ajax.

2. Split the front-end code of table data and paging function

1) The order_data_tables.html code file stores table data.

<table class="table-content table table-bordered table-hover">
    <thead class="thead-dark">
    <tr>
        <th>Brand</th>
        <th>Product name</th>
        <th>Item number</th>
        <th>Order number</th>
        <th>Color</th>
        <th>Purchase price</th>
        <th>Retail price</th>
        <th>Net profit</th>
        <th>Quantity</th>
    </tr>
    </thead>
    <tbody style="font-size: 14px;">
    {% for data in order_page_data %}
        <tr>
            <td>{<!-- -->{ data.brand }}</td>
            <td>{<!-- -->{ data.commodity_name }}</td>
            <td>{<!-- -->{ data.commodity_number }}</td>
            <td>{<!-- -->{ data.order_number }}</td>
            <td>{<!-- -->{ data.commodity_color }}</td>
            <td>{<!-- -->{ data.purchasing_price }}</td>
            <td>{<!-- -->{ data.retail_price }}</td>
            <td>{<!-- -->{ data.profit }}</td>
            <td>{<!-- -->{ data.quantity }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

2) The order_data_page.html code file stores the paging function.

<ul class="pagination justify-content-center">
    {% if order_page_data.has_previous %}
        <li class="page-item">
            <a class="page-link" href="?page={<!-- -->{ order_page_data.previous_page_number }}" data-page={<!-- -->{ order_page_data.previous_page_number }}>Previous page</a>
        </li>
    {% else %}
        <li class="page-item disabled">
            <a class="page-link">Previous page</a>
        </li>
    {% endif %}

    {% for page in order_page_data.paginator.page_range %}
        <li class="page-item {% if page == order_page_data.number %}active{% endif %}">
            <a class="page-link" href="#" data-page="{<!-- -->{ page }}">{<!-- -->{ page } }</a>
        </li>
    {% endfor %}

    {% if order_page_data.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={<!-- -->{ order_page_data.next_page_number }}" data-page={<!-- -->{ order_page_data.next_page_number }}>Next page</a>
        </li>
    {% else %}
        <li class="page-item disabled">
            <a class="page-link">Next page</a>
        </li>
    {% endif %}
</ul>

3) order_data_page.html The table and paging code are still retained in the front-end code file of the total page.

bf3e3d7751ca60c8f64e589707232b4a.png

3. The backend handles paging functions and Ajax requests

Paging is very simple to implement. It mainly handles Ajax requests. When the request is Ajax, the order_data_tables.html (front-end file of table data) and order_data_page.htm (pagination front-end file) renders with the paging parameters passed by the back-end, returns the rendered HTML in the form of a string, and stores it in a variable. At this step, The table data and paging styles corresponding to a certain page visited this time have all been rendered.

Then use the JsonResponse() method to return the variables storing table and paging data to the front end in JSON format.

from django.http import HttpResponse, JsonResponse
from django.template.loader import render_to_string


def order_manage_beautiful(request):
    order_data = OrderManage.objects.order_by('-id')
    
······

    # Pagination
    order_pages = Paginator(order_data, 10)
    order_page_num = int(request.GET.get("page", 1))
    if order_page_num > order_pages.count:
        order_page_num = 1

    order_page_data = order_pages.page(order_page_num)

    # Determine whether it is an Ajax request. If it is an Ajax request, render the table data and paging front-end code and return it to the front-end in Jason format.
    if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
        #The render_to_string method will render the front-end code and back-end parameters and return them to html text
        order_table_html = render_to_string("order_data_tables.html", {"order_page_data": order_page_data})
        order_page_html = render_to_string("order_data_page.html", {"order_page_data": order_page_data})
        return JsonResponse({"order_table_html": order_table_html, "order_page_html": order_page_html})

    return render(request, "order_manage_beautiful.html", {"is_file": is_file, "order_data": order_data, "order_page_data": order_page_data})

The returned Json is as follows.

7272d10738f84e0993ada8e502b6ba28.png

4. Write code for Ajax request for paging data

4.1. Bind the ID attribute to the code in the table part

Bind an ID attribute to the upper div tag of the table: id="order_table". After Ajax gets the new data, it must be rendered in this tag to complete the dynamic update of the table data.

<div class="card-body" id="order_table">
    <table class="table-content table table-bordered table-hover">
        <thead class="thead-dark">
        <tr>
            <th>Brand</th>
            <th>Product name</th>
            <th>Item number</th>
            <th>Order number</th>
            <th>Color</th>
            <th>Purchase price</th>
            <th>Retail price</th>
            <th>Net profit</th>
            <th>Quantity</th>
        </tr>
        </thead>
        <tbody style="font-size: 14px;">

        {% for data in order_page_data %}
            <tr>
                <td>{<!-- -->{ data.brand }}</td>
                <td>{<!-- -->{ data.commodity_name }}</td>
                <td>{<!-- -->{ data.commodity_number }}</td>
                <td>{<!-- -->{ data.order_number }}</td>
                <td>{<!-- -->{ data.commodity_color }}</td>
                <td>{<!-- -->{ data.purchasing_price }}</td>
                <td>{<!-- -->{ data.retail_price }}</td>
                <td>{<!-- -->{ data.profit }}</td>
                <td>{<!-- -->{ data.quantity }}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</div>

4.2. Bind the ID attribute to the code of the paging function

It is still bound in the upper div tag of the paging function: id="order_page".

<div aria-label="Page navigation example" style="margin-top: 20px;" id="order_page">
    <ul class="pagination justify-content-center">
                {% if order_page_data.has_previous %}
                    <li class="page-item">
                        <a class="page-link" href="?page={<!-- -->{ order_page_data.previous_page_number }}" data-page={<!-- -->{ order_page_data.previous_page_number }}>Previous page</a>
                    </li>
                {% else %}
                    <li class="page-item disabled ">
                        <a class="page-link">Previous page</a>
                    </li>
                {% endif %}

                {% for page in order_page_data.paginator.page_range %}
                    <li class="page-item {% if page == order_page_data.number %}active{% endif %}">
                        <a class="page-link" href="#" data-page="{<!-- -->{ page }}">{<!-- -->{ page } }</a>
                    </li>
                {% endfor %}

                {% if order_page_data.has_next %}
                    <li class="page-item">
                        <a class="page-link" href="?page={<!-- -->{ order_page_data.next_page_number }}" data-page={<!-- -->{ order_page_data.next_page_number }}>Next page</a>
                    </li>
                {% else %}
                    <li class="page-item disabled">
                        <a class="page-link">Next page</a>
                    </li>
                {% endif %}
     </ul>
</div>

4.3. Write Ajax to implement dynamic update of paging data

When the tag with class page-link is clicked (the paging box is clicked), an Ajax request is triggered, requesting the /order_manage_beautiful interface and passing page Parameters, after successful access, a JSON format data will be returned. Render the data of data.order_table_htmlKey in JSON to the div of the table, and render data.order_page_htmlKey’s data is rendered into the paging div.

$(document).on('click', '.page-link', function(e) {
  e.preventDefault();
  var page = $(this).data('page')
  $.ajax({
    url: '/order_manage_beautiful',
    type: "GET",
    data: {page: page},
    success: function(data) {
        // Render table data
        $('#order_table').html(data.order_table_html);

        // Render paging function
        $('#order_page').html(data.order_page_html);
    }
  });
});

4.4. Effect display

ca1aabb5f5762277e06c520cc1509e4d.png