Dev360.com - Web Development and Beyond

In a split-second, customers will determine if your site is worthy of their time. Can you afford to lose them?

Blog

Categories

Archive for June, 2009

ManyToManyField and Ordered fields in Django ModelForms

Monday, June 15th, 2009

I was working on some code and realized that ManyToManyFields always show up last in a ModelForm, regardless if you specify the order in the Meta fields property. Apparently this is due to be fixed in Django 1.1 which is right around the corner.. unfortunately I’m on 1.0 and feel anxious about moving 10+ sites to 1.1 beta right at this moment. I also felt it was a bit inappropriate to diff my Django source.

Please be aware that this is a hack. It is not an optimal solution. Stuff like form.as_* will NOT work with the solution below. All this does is add a property called ordered_fields to your ModelForm which implements the correct behavior.

# models.py
class Bar(models.Model):
	pass

class Foo(models.Model):
        # ordinarily, Django 1.0 would list the regular_field first and all M2Ms last
	many_to_many = models.ManyToManyField('Bar', related_name='foos')
	regular_field = models.CharField(max_length=10)
# forms.py
class FooForm(forms.ModelForm):
	def ordered_fields(self):
		list = []
		for field_name in self._meta.fields:
			list.append(self[field_name])
		return list

	class Meta:
		model = Foo
		fields = ('many_to_many',
			     'regular_field',)
#Template:

<form action="{{ app_path }}" method="post" id="foo-form">
	<fieldset class="module aligned ()">
	{% for field in form.ordered_fields %}
		<div class="form-row thin wide ()">

			{{ field.label_tag }}
			{{ field }}
			{{ field.errors }}
			{% if field.help_text %}
			<p class="help">{{ field.help_text }}</p>
			{% endif %}
		</div>
	{% endfor %}
	</fieldset>
	<div class="submit-row aligned ()">
		<input class="default" type="submit" value="Send" />
	</div>
</form>

ImageField not validating in Django ModelForm

Friday, June 5th, 2009

The other day I was working on a Django ModelForm that had an ImageField in it and to my great surprise the ImageField would not validate in the ModelForm, even when I had selected an image. The solution was simple enough: add request.FILES to the instantiation parameters of the ModelForm.. DUH!

    #ProfileForm is a ModelForm
    form = ProfileForm(request.POST, request.FILES, instance=profile)