You are hereWeb API using Django and markup.py

Web API using Django and markup.py


By meledictas - Posted on 16 November 2008

I have a web application that has a set of web api. I want it to be XML base. Django has utilities to serialize the query set to json or XML but I want to output XML that is not django' format. Below is how I did that.

The XML generator

I use markup.py, intuitive, light weight, easy-to-use, customizable and pythonic HTML/XML generator (from its website). I didn't spend much time on this. You can use any XML generator.

Below is how I generate the XML,

import markup

def get_lastest_post_api(request, num_post):
    posts = Post.objects.order_by('-created')[:int(num_post)]
    xml_response = get_post_xml_response(get_post_xml_response(posts))
    return HttpResponse(
        xml_response,
        mimetype='text/xml',
    )

def get_post_xml_response(posts):
    xml = markup.page(mode='xml')
    xml.init(encoding='utf-8')
    xml.posts.open()
    for post in posts:
        xml.post.open()
        xml.title(_(post.title))
        xml.user(_(post.user.username))
        xml.body(_(post.body))
        xml.date(_(str(post.created)))
        xml.tags(_(post.tags))
        xml.allow_comments(post.allow_comments)
        xml.post.close()
    xml.posts.close()

    return xml

The XML generator _getpost_xml_response__ function take the query set as a parameter. It construct the markup, set the encoding to utf-8 and start the generation.

The XML generation is simple. I use xml.posts.open() to open the posts tag. After that, I iterate over the query set and create post tag and fill in the detail for each. To close the each post tag I use xml.post.close()

The XML Output

Below is example,

<?xml version='1.0' encoding='utf-8' ?>
<posts>
    <post>
        <title>python-markdown2</title>
        <user>admin</user>
        <body>this is the post body
        <date>2008-11-04 18:34:30.879000</date>
        <tags>python django markup</tags>
        <allow_comments>True</allow_comments>
    </post>
</posts>