For work recently I've been doing some
Django-related tasks that involve talking to an external API with
POSTed forms. Django forms objects are declared by creating a class that
django.forms.Form, with the fields of the
form declared by declaring attributes of that class. Which works well
and is clean and easy to remember—unless the API you're working
with requires a field with the same name as a Python keyword, such as
return. You can't declare a field like this as an
attribute; it will trigger a syntax error.
I spent some time scratching my head over this, and came up with this as
a workaround after source-diving to find out how
objects actually work:
from django import forms class ExampleForm(forms.Form): def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, errorclass=ErrorList, label_suffix=':', empty_permitted=False, return_url=None): forms.Form.__init__(self, data, files, auto_id, prefix, initial, errorclass, label_suffix, empty_permitted) if return_url is not None: self.fields['return'] = forms.CharField(widget=forms.HiddenInput, initial=return_url)
It turns out that the attribute declaration is just syntactic sugar for
creating a dictionary of key/value pairs, which is then stored in the
fields attribute. So we can monkeypatch in extra values after
the translation. Which is somewhat more awkward and ugly, but works in a pinch.
Note that I haven't extensively tested what interactions this may cause with other forms code, so use with some caution.