Categories
Python Answers

How to access the request object or any other variable in a form’s clean() method with Python Django?

To access the request object or any other variable in a form’s clean() method with Python Django, we can use self.request in the clean method to access the request object.

For instance, we write

class MyForm(forms.Form):

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(MyForm, self).__init__(*args, **kwargs)


    def clean(self):
        self.request
        # ...  

to create the MyForm form with the clean method.

And then we can use self.request to access the request object in the clean method.

Categories
Python Answers

How to create a custom 500/404 error page with Python Django?

To create a custom 500/404 error page with Python Django, we can set the response object to the error code we want and return it.

For instance, we write

from django.shortcuts import render_to_response
from django.template import RequestContext


def handler404(request, *args, **argv):
    response = render_to_response('404.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 404
    return response


def handler500(request, *args, **argv):
    response = render_to_response('500.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 500
    return response

to call render_to_response with the template URL to create the response object.

And then we set the status_code to 404 or 500.

Then we return it.

Categories
Python Answers

How to filter a QuerySet with dynamic field lookups with Python Django?

To filter a QuerySet with dynamic field lookups with Python Django, we can pass in dynamic arguments to filter.

For instance, we write

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}

Person.objects.filter(**kwargs)

to unpack the kwargs dictionary as arguments for filter so we can pass in any number of arguments we want into it.

Categories
Python Answers

How to redirect to previous page after login with Python Django?

To redirect to previous page after login with Python Django, we change some settings and then add the previous page URL into the template,

For instance, we write

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.request",
)

to add the django.core.context_processors.request and django.core.context_processors.auth template context processors.

Then we add the URL by writing

<a href="{% url django.contrib.auth.views.login %}?next={{request.path}}">Login</a>

to add the django.contrib.auth.views.login URL as the URL with the request.path path set to the redirect URL in base.html so the login form submit button will redirect to the request.path.

And then we add

{% block content %}
<form method="post" action="">
  {{form.as_p}}
<input type="submit" value="Login">
</form>
{% endblock %}

to add the login form.

Categories
Python Answers

How to render HTML to PDF in a Python Django site?

To render HTML to PDF in a Python Django site, we can create our own function.

For instance, we write

import cStringIO as StringIO
from xhtml2pdf import pisa
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
from cgi import escape


def render_to_pdf(template_src, context_dict):
    template = get_template(template_src)
    context = Context(context_dict)
    html  = template.render(context)
    result = StringIO.StringIO()

    pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), result)
    if not pdf.err:
        return HttpResponse(result.getvalue(), content_type='application/pdf')
    return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))

to define the render_to_pdf function that uses the pisa.pisaDocument constructor to create the PDF from the html string.

We get html from render the template with the context to a HTML string.

Then we create a new HttpResponse that returns the PDF file as the response.

We set the content_type to application/pdf.

And we render result.getvalue to return the PDF.

Then in our view, we add

def myview(request):
    return render_to_pdf(
            'mytemplate.html',
            {
                'pagesize':'A4',
                'mylist': results,
            }
        )

to render the mytemplate.html template into a PDF and return it as the response with render_to_pdf.

And then in mytemplate.html, we write

<!DOCTYPE HTML>
<html>
    <head>
        <title>My Title</title>
        <style type="text/css">
            @page {
                size: {{ pagesize }};
                margin: 1cm;
                @frame footer {
                    -pdf-frame-content: footerContent;
                    bottom: 0cm;
                    margin-left: 9cm;
                    margin-right: 9cm;
                    height: 1cm;
                }
            }
        </style>
    </head>
    <body>
        <div>
            {% for item in mylist %}
                RENDER MY CONTENT
            {% endfor %}
        </div>
        <div id="footerContent">
            {%block page_foot%}
                Page <pdf:pagenumber>
            {%endblock%}
        </div>
    </body>
</html>