Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to serialize a pagination object in Django?

I'm using Django pagination with jQuery. I can serialize the objects list of the pagination object, but I'd like to serialize the whole object to get more data (page number, total number of pages...). How can I serialize the whole pagination object?

Thanks

javascript

function getRestaurants(query) {

        $.post("/getRestaurant/", query,
            function(data) {
                /* do stuff with data */
             },"json" );
}

views.py

def getRestaurant(request):

    results = Restaurant.objects.all()
    paginator = Paginator(restaurants, 5)

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.POST.get('page','1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        results = paginator.page(page)
    except (EmptyPage, InvalidPage):
        results = paginator.page(paginator.num_pages)

    data=serializers.serialize("json", results.object_list) #I'd like to serialize the whole results object

    return HttpResponse(data)
like image 678
jul Avatar asked Feb 03 '23 08:02

jul


2 Answers

I've just had to make a hacky solution for this so I'll post it as an answer - any improvements welcome:

from django.core import serializers
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.serializers.json import DjangoJSONEncoder
from django.http import HttpResponse
from django.utils import simplejson  
from types import MethodType 

from mysite.tasks.models import Task

PER_PAGE = 20

def list(request):
    """
    Return a paginated JSON object.
    """

    paginator = Paginator(tasks.objects.all(), PER_PAGE) 
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        pagetasks = paginator.page(page)
    except (EmptyPage, InvalidPage):
        pagetasks = paginator.page(paginator.num_pages)

    # Dump the Page attributes we want to a dictionary
    serializedpage = {}
    wanted = ("end_index", "has_next", "has_other_pages", "has_previous",
            "next_page_number", "number", "start_index", "previous_page_number")
    for attr in wanted:
        v = getattr(tasks, attr)
        if isinstance(v, MethodType):
            serializedpage[attr] = v()
        elif isinstance(v, (str, int)):
            serializedpage[attr] = v

    # Serialise the queryset to plain Python objects 
    # and add them to the serialized page dictionary
    pythonserializer = serializers.get_serializer("python")()
    serializedpage["object_list"] = pythonserializer.serialize(pagetasks.object_list, 
            fields=('task_id', 'task_data')) 

    # Dump it as JSON using the Django encoder
    response = HttpResponse(mimetype="application/json")
    simplejson.dump(serializedpage, response, cls=DjangoJSONEncoder)
    return response                               
like image 84
Mikesname Avatar answered Feb 06 '23 06:02

Mikesname


my suggestion is to discard the paginator object & slice the queryset yourself. this way you could easily serialize the output.

as an example, here's how you might wanna do that if you wanna serialize a list of comments into json format:

comment_list = ArticleComment.objects.filter(article__id=int(_id), is_public=True).values('created', 'tag', 'content', 'author').order_by('-created')   
    start = (page_num - 1) * COMMENTS_PER_PAGE
    end = page_num * COMMENTS_PER_PAGE
    return HttpResponse(json.dumps(list(comment_list[start:end]), cls=DjangoJSONEncoder))
like image 32
mmbrian Avatar answered Feb 06 '23 04:02

mmbrian