Skip to content


Two Django snippets

Last 2-3 days I’ve been working on this new site project. As (almost) all web projects I started last 2 years, I’m using the Django framework to develop the site, as I just love it for several reasons.

Tonight I’d like to share 2 snippets. The first one is one I use quite regularly. It’s a replacement for django.shortcuts.render_to_response, which requires one to always add a RequestContent keyword argument to be able to access MEDIA_URL etc in templates.

This replacement (which I mostly put in utils/shortcuts.py) is completely API-compatible with the default render_to_response implementation, but if you pass it a request object as first parameter (and no context_instance), it automaticly uses a RequestContext.

from django.shortcuts import render_to_response as real_render_to_response
from django.http import HttpRequest
from django.template.context import RequestContext

def render_to_response(*args, **kwargs):
    # Check old API
    if len(args) > 0 and not isinstance(args[0], HttpRequest):
        return real_render_to_response(*args, **kwargs)
    if not kwargs.get('context_instance', None):
        kwargs['context_instance'] = RequestContext(args[0])

    return real_render_to_response(*args[1:], **kwargs)

The second one is an custom form which can be used with the django-contact-form application. It automaticly uses the name and email address of the user if logged in, otherwise provides the standard text input fields.

It might be a good example of how to implement a custom widget, and how to set per-form-instance values of widgets.

Do note you will need to change some things around line 29.

class ConstOrTextInput(forms.TextInput):
    def __init__(self, *args, **kwargs):
        super(ConstOrTextInput, self).__init__(*args, **kwargs)
        self.const_value = None

    def value_from_datadict(self, *args, **kwargs):
        if not self.const_value:
            return super(forms.TextInput, self).value_from_datadict(*args, **kwargs)
        return self.const_value

        def render(self, *args, **kwargs):
            if not self.const_value:
                return super(forms.TextInput, self).render(*args, **kwargs)
            else:
                from django.utils.safestring import mark_safe
                return mark_safe(u'' % self.const_value)

class UserdataContactForm(ContactForm):
    name = forms.CharField(max_length=100,
                                           widget=ConstOrTextInput(attrs=attrs_dict),
                                           label=u'Your name')
    email = forms.EmailField(widget=ConstOrTextInput(attrs=dict(attrs_dict,
                                           maxlength=200)),
                                           label=u'Your email address')

    def __init__(self, data=None, request=None, *args, **kwargs):
        super(UserdataContactForm, self).__init__(data, request, *args, **kwargs)
        if request.user.is_authenticated():
            self.fields['name'].widget.const_value = request.user.get_profile().get_display()
            self.fields['email'].widget.const_value = request.user.email
        else:
            self.fields['name'].widget.const_value = None
            self.fields['email'].widget.const_value = None

    def from_email(self):
        if self.request and self.request.user.is_authenticated():
            return self.request.user.email
        else:
            return super(UserdataContactForm, self).from_email

I added this to the end of the forms.py from the django-contact-form application, if you place it elsewhere, some more changes might be necessary.

I hope this is useful for at least someone!

Posted in Development.

Tagged with , .


2 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Tim says

    You should take a look at django generic views : http://www.djangoproject.com/documentation/generic_views/

  2. Nicolas says

    I, obviously, know about generic views. I think you’re refering to django.views.generic.simple.direct_to_template? It does provide the same functionality indeed, but I think the above solution could be somewhat more useful to counter arguments given in Django bug #5949.



Some HTML is OK

or, reply to this post via trackback.