【问题标题】:Django ajax pagination couldn’t run properlyDjango ajax 分页无法正常运行
【发布时间】:2021-06-16 13:42:12
【问题描述】:

我想使用 jquery ajax 在 django 中实现分页。我正在尝试某种方式,但它不起作用。这是我的views.py:

def post_list(request):
posts = Post.published.all()

results_per_page = 3
paginator = Paginator(posts, results_per_page)

page_number = request.GET.get('page')
posts = paginator.get_page(page_number)
if request.is_ajax():
    posts_html = render_to_string('posts.html',
                {'posts': posts}
    )
    data_dict = {
        'posts_html': posts_html
    }
    return JsonResponse(data=data_dict)
    
return render(request, 'post_list.html', {'posts':posts})

而我的 pagination.py 如下:

<nav id="pagination">
<ul class="pagination">
{% if posts.has_previous %}
<li class="page-item">
  <a class="page-link" href="{{ request.path }}?page={{ posts.previous_page_number }}" aria-label="Previous">
    <span aria-hidden="true">&laquo;</span>
    <span class="sr-only">Previous</span>
  </a>
</li>
{% endif %}
{% for i in posts.paginator.page_range %}
{% if posts.number == i %}
<li class="page-item active">
  <a class="page-link" href="{{ request.path }}?page={{ i }}" >{{ i }}</a>
</li>
{% else %}
<li class="page-item">
  <a class="page-link" href="{{ request.path }}?page={{ i }}" >{{ i }}</a>
</li>
{% endif %}
{% endfor %}
{% if posts.has_next %}
<li class="page-item">
  <a class="page-link" href="{{ request.path }}?page={{ posts.next_page_number }}" aria-label="Next">
    <span aria-hidden="true">&raquo;</span>
    <span class="sr-only">Next</span>
  </a>
</li>
{% endif %}

还有我的js文件:

{% block js %}
<script type="text/javascript">
  function ajaxPagination() {
    $('#pagination a.page-link').each((index, el) => {
        $(el).click(function(e) {
            e.preventDefault()
            let page_url = $(el).attr('href')
            console.log(page_url)
            $.ajax({
                type: 'GET',
                url: page_url,
                dataType: 'json',
                success: function(response) {
                    $('#posts').html(response['posts_html'])
                }
            })
        })
    })
}  
$(document).ready(function() {
    ajaxPagination()
})

$(document).ajaxStop(function() {
    ajaxPagination()
})
</script>
{% endblock js %}

我找不到任何关于此问题的详细教程/指南。
开发者!请告诉我如何使用 jquery ajax 在 django 中实现分页?

提前致谢。

【问题讨论】:

    标签: jquery django ajax pagination


    【解决方案1】:

    在我在这里发布问题后,但我没有得到任何答案。我尝试了不同的申请方式,但没有一个对我有用。 Django 内置的 Pagination 很容易用于同步视图。但是如何使用 Json 响应来异步调用呢?对于像我这样的初学者来说,这更加令人困惑。这让我恐慌了好几天。最后,我找到了一种使用 Jquery 实现的简单方法。虽然我最初的问题是“Django ajax 分页无法正常运行”,但我知道开发人员!我只是向您展示我们如何以不同的方式实现相同的目标。所以,我想分享一下我的经验:

    views.py

    def post_list(request):
        posts = Post.objects.all()
        context = {
            'posts': posts,
        }
        return render(request, 'post_list.html', context)
    

    post_list.html

    {% block page_content %}
    <div id="page">
        {% include 'posts.html' %}
    
        <div class="container">
            <nav aria-label=...>
                <ul class=pagination>
                    <li id="previous-page"><a class="page-link" href="javascript:void(0)" aria-label=Previous><span aria-hidden=true>&laquo;</span></a></li>
                </ul>
            </nav>
        </div>
    </div>
    {% endblock page_content %}
    
    {% block js %}
    <script>
        $(document).ready(function(){
           var numberOfItems = $('#page .post-col').length; // Get total number of the items that should be paginated
    var limitPerPage = 4; // Limit of items per each page
    $("#page .post-col:gt(" + (limitPerPage - 1) + ")").hide(); // Hide all items over page limits (e.g., 5th item, 6th item, etc.)
    var totalPages = Math.round(numberOfItems / limitPerPage); // Get number of pages
    $(".pagination").append("<li class='page-item active'><a class='page-link' href='javascript:void(0)'>" + 1 + "</a></li>"); // Add first page marker
    // Loop to insert page number for each sets of items equal to page limit (e.g., limit of 4 with 20 total items = insert 5 pages)
    for (var i = 2; i <= totalPages; i++) {
      $(".pagination").append("<li class='page-item'><a class='page-link' href='javascript:void(0)'>" + i + "</a></li>"); // Insert page number into pagination tabs
    }
        
    // Add next button after all the page numbers 
    $(".pagination").append("<li id='next-page'><a class='page-link' href='javascript:void(0)' aria-label=Next><span aria-hidden=true>&raquo;</span></a></li>")
    // Function that displays new items based on page number that was clicked
    $('.pagination li.page-item').on('click',  function() {
      // Check if page number that was clicked on is the current page that is being displayed
        if ($(this).hasClass('active')) {
            return false;
        } else {
            var currentPage = $(this).index(); // Get the current page number
            $('.pagination li').removeClass('active'); // Remove the 'active' class status from the page that is currently being displayed
            $(this).addClass('active'); // Add the 'active' class status to the page that was clicked o
            $('#page .post-col').hide(); // Hide all items in loop, this case, all the list groups
            
            var grandTotal = limitPerPage * currentPage; // Get the total number of items up to the page number that was clicked o
            // Loop through total items, selecting a new set of items based on page number
            for (var i = grandTotal - limitPerPage; i < grandTotal; i++) {
                $("#page .post-col:eq(" + i + ")").show(); // Show items from the new page that was selected
            }   
        }
      });
      // Function to navigate to the next page when users click on the next-page id (next page button)
      $('#next-page').on('click', function() {
          var currentPage = $('.pagination li.active').index(); // Identify the current active page
          // Check to make sure that navigating to the next page will not exceed the total number of pages
          if (currentPage === totalPages) {
              return false; // Return false (i.e., cannot navigate any further, since it would exceed the maximum number of pages)
          } else {
              currentPage++; // Increment the page by one
              $('.pagination li').removeClass('active'); // Remove the 'active' class status from the current page
              $('#page .post-col').hide(); // Hide all items in the pagination loop
              var grandTotal = limitPerPage * currentPage; // Get the total number of items up to the page that was selected
              // Loop through total items, selecting a new set of items based on page number
              for (var i = grandTotal - limitPerPage; i < grandTotal; i++) {
                  $("#page .post-col:eq(" + i + ")").show(); // Show items from the new page that was selected
              }
              $(".pagination li.page-item:eq(" + (currentPage - 1) + ")").addClass('active'); // Make new page number the 'active' page
          }
          
    });
    $('#previous-page').on('click', function() {
        var currentPage = $('.pagination li.active').index();
        if (currentPage === 1) {
            return false;
        } else {
            currentPage--;
            $('.pagination li').removeClass('active');
            $('#page .post-col').hide()
            var grandTotal = limitPerPage * currentPage
            for (var i = grandTotal - limitPerPage; i < grandTotal; i++) {
                $("#page .post-col:eq(" + i + ")").show();
            }
            $(".pagination li.page-item:eq(" + (currentPage - 1) + ")").addClass('active')
        }
            
       });
     });
    </script>
    {% endblock js %}
    

    posts.html

    <div class="row">
      {% for post in posts %}
      <div class="col-md-6 post-col">  
        <div class="card flex-md-row mb-4 shadow-sm h-md-250">
            {% if post.main_image %}
            <img class="card-img-left flex-auto d-none d-lg-block" data-src="holder.js/200x250?theme=thumb" alt="Thumbnail [200x250]" style="width: 200px; height: 250px;" src="{{ post.main_image.url }}" data-holder-rendered="true">
            {% endif %}
            <div class="card-body d-flex flex-column align-items-start">
              <strong class="d-inline-block mb-2 text-primary">World</strong>
              <h3 class="mb-0">
                <a class="text-dark" href="{% url 'post_detail' post.slug %}">{{post.title}}</a>
              </h3>
              <div class="mb-1 text-muted">Nov 12</div>
              <p class="card-text mb-auto">{{post.summary}}</p>
              <a href="{% url 'post_detail' post.slug %}">Continue reading</a>
            </div>
        </div>
      </div>
      {% endfor %}
    </div>
    

    希望。这对初学者会有帮助。有什么想法吗?请与我分享。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-27
      • 1970-01-01
      • 2011-02-23
      • 2018-11-05
      • 2021-12-12
      • 1970-01-01
      • 2017-06-18
      相关资源
      最近更新 更多