You are hereBlogs > tonkla's blog > ตกแต่ง Pagination ด้วย Inclusion Tags

ตกแต่ง Pagination ด้วย Inclusion Tags


By tonkla - Posted on 17 October 2008

จากบันทึก "ทำ simple tag ใช้เอง" ของ @jittat คราวก่อน ทำให้เราพอจะเห็นภาพของ custom tag ชนิดแรกไปบ้างแล้ว คราวนี้ลองมาดูอีกชนิดหนึ่ง ซึ่งก็คือ inclusion tag ครับ

และจากบันทึกก่อนหน้านี้ "include tag และ ajax" ทำให้เราพอจะสรุปง่ายๆ ได้ว่า

simple tag + include tag = inclusion tag

นั่นก็คือ inclusion tag มันทำงานเหมือน simple tag แต่ต้องการ template เพื่อมาแสดงผลลัพธ์

สาเหตุที่ทำให้ต้องมาใช้ inclusion tag คือผมต้องการทำ pagination ครับ ซึ่ง django ก็มีมาให้ใช้อย่างสะดวกโยธิน เพียงแต่การแสดงผลมันยังไม่ใช่อย่างที่ต้องการ เท่าที่ลองค้นหา plug-in ดู ก็พบว่ามีคนทำ django-pagination ไว้แล้ว แต่จากการลองใช้ คาดว่ามันมีบั๊กครับ บั๊กที่ว่านี้คือมันจะไม่แสดง pagination หาก page=1 ซึ่งจริงๆ แล้วอาจจะเป็นแค่ค่า setting อะไรสักบรรทัดแค่นั้นเอง แต่ผมขี้เกียจหา -_-'

ผมจึงลองหาวิธีอื่นต่อ พบว่ามี Paginator Tag ให้ใช้ แต่ก็มีคนสมองใสนำมาพัฒนาต่อยอด จนได้ Digg-style pagination in Django ออกมาอีก ซึ่งการจะใช้เจ้านี่ได้ เราต้องไปทำความเข้าใจกับ inclusion tag ครับ : )

อ่อ อีกนิดครับ สองตัวนี้ใช้ object_list ในการทำ pagination นะครับ ไม่ได้ใช้ QuerySet ตามปกติ สรุปว่ากว่าจะใช้ pagination ได้ต้องศึกษา generic view เพิ่มอีกตัว (จริงๆ แล้วนิดเดียว ไม่เยอะ)

ลองมาดูตัวอย่างอย่างย่อกันครับ เวอร์ชั่นเต็มดูได้จากลิงก์ข้างบน

templatetags/common_tags.py

@register.inclusion_tag("paginator.html", takes_context=True)
def paginator(context):
    """ code here """

templates/paginator.html

template สำหรับแสดงผล pagination ดูได้จากต้นฉบับครับ

news/views.py

from django.views.generic.list_detail import object_list

def show_news_by_category(request, category):
    c = Category.objects.filter(slug=category)
    if not c: raise Http404
    n = News.objects.filter(category__in=c).order_by('-created_at')
    ctx = {'title': c.name}
    return object_list(request, queryset=n, extra_context=ctx, paginate_by=ITEMS_PER_PAGE)

templates/news/news_list.html

{% load common_tags %}
{% for obj in object_list %}
  <div class="item">
    <a href="/categories/{{ obj.category.slug }}/news/{{ obj.id }}">{{ obj.title }}</a>
  </div>
{% endfor %}
{% paginator %}