Reporting in Django

The Django application I’m developing has a reporting need: paper (PDF) output of reports, both 8 1/2 X 11 and special forms (labels, name tags, etc.). So, I’ve begun evaluating my reporting options.

Unfortunately, I haven’t found very many methods to examine, probably because of my requirements:

Python based
Since I’m using Python/Django for the rest of the work, it would make sense to use Python for this component as well. Other folks that may someday support the application will appreciate having a single skill set to maintain.
Contained in the Application
I’ve found at least one system that runs as a separate service on a server, but that is more complexity than I would like to introduce into a client’s technology stack. This application will appeal to small offices that likely don’t have strong tech support. Adding a separate service (in this example, Java/Tomcat) on top of Django, MySQL and Apache is more than many can do, and I certainly don’t want to get into the server admin business on their behalf.
Open Source
Another issue that the clients won’t want to deal with is licensing to third parties. I’m using all open source tools to build and run the application, and it wouldn’t make sense to require a potential customer to license something before they could use it. Plus, would I have to become a reseller for the licensed software?
Integrated with Django
This is total ‘wish list’ stuff, but wouldn’t it be neat to have an interface similar to the Django templating system where I could bring in data from a view into a report ‘template’?

Looking through Google searches, I’ve found that the terms “reports” and “reporting” can mean different things to different people. Since I’m looking to generate paper, I have been looking at Geraldo, which uses the ReportLab library to generate PDF output. This application looks promising, but is still a work in progress. I’m finding that flexible formatting with variable length text is a difficult, and maybe impossible, thing to do.

I’d like to hear from others on this subject. Have you found a good package for reporting? Are you developing one? Please leave your thoughts in the comments.

Accessing the Value of a Form Field in a Template

(This is a ‘Note to Self’ post)

I’ve been trying for half the day to get radio buttons in a custom template to work. The buttons are generated in a for loop that builds a table row for each choice (iterating over a queryset called cls), including this code for the row’s radio button:

input type="radio" name="reg_choice_1" value="{{ cls.id }}"
 {% ifequal srform.reg_choice_1 cls.id %}CHECKED{% endifequal %}

The goal is to have the ifequal test tell me if the row’s cls.id matches the value set in the form. However, I didn’t know how to access that value. After many Google searches, perusal of the Django documentation, and even a failed attempt to follow the template rendering code, I was stumped. As a wild guess, I tried the .data attribute, and it worked! Here’s the updated (and functional) code:

input type="radio" name="reg_choice_1" value="{{ cls.id }}" 
{% ifequal srform.reg_choice_1.data cls.id %}CHECKED{% endifequal %}

I hope that I’ve put enough keywords in this post so that future stumped Djangonauts can find some help.

As always, leave your comments below.

Full URL in Django

The application I’m developing includes an XML feed, in which one of the items is a URL Unfortunately, using the {% url %} tag in the template only gives the path portion of the URL. Time for a little research.

Many web posts pointed me to the Sites framework included with Django, as it can return the domain for the site. I tried it out, and it worked, but I didn’t like how it would have to be implemented in my multiple server scenario (laptop, DEV server, QA server, Production). Each would have to have any entry in the sites table, and the SITE_ID in the settings.py file for each instance would have to point to the correct entry. This would be awkward at best, and would limit the possibility of making the application reusable.

A couple of bloggers mentioned using RequestSite instead. It shares the same API with the Sites class, but doesn’t use the sites table. Instead, the domain name is pulled from the request object. Here’s a sample of the view logic:

   from django.contrib.sites.models import RequestSite    
    site_name = RequestSite(request).domain
    
    return render_to_response('template.xml', 
                              {'entries': queryset, 'site_name' : site_name}, 
                              context_instance=RequestContext(request), 
                              mimetype='text/xml')

After pulling the domain from the request, it is passed along to the template in the context dictionary. In the template, I can reference the variable ‘site_name‘ in front of the {% url %} tag. However, before I have a full URL, I also need to know the protocol.

Another blog post demonstrated the is_secure attribute of the request object. Testing this attribute can help us determine is the protocol is http or https. The temple code for a full URL is:

{% if request.is_secure %}https{% else %}http{% endif %}://{{ site_name }}
{% url entry e.pk %}

Maybe a little clumsy, but it gets the job done without hard coding anything.

I’d love to hear your thoughts in the comments.

Is Short Sweet?

I was reading this post by Jacob Kaplan-Moss on Dynamic Form Generation, and this little side point caught my interest. He pointed out a more compact way to write a view for a create operation.

OLD WAY:

from django.shortcuts import redirect, render_to_response
from myapp.forms import UserCreationForm

def create_user(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            do_something_with(form.cleaned_data)
            return redirect("create_user_success")
    else:
        form = UserCreationForm()

    return render_to_response("signup/form.html", {'form': form})

NEW WAY:

def create_user(request):
    form = UserCreationForm(request.POST or None)
    if form.is_valid():
        do_something_with(form.cleaned_data)
        return redirect("create_user_success")

    return render_to_response("signup/form.html", {'form': form})

Now, I’m all for keeping things concise, but I’m not sure if this new way is as clear. I want to keep my code readable for those that are tasked with maintaining it someday can understand it.

What do you think? Is the 2nd method OK when others need to read the code?