Opened 8 years ago

Closed 5 years ago

#6953 closed Bug (fixed)

ModelForm as_FOO output places form fields for ManyToMany fields at bottom of html output.

Reported by: brooks.travis@… Owned by: Alex Gaynor
Component: Forms Version: master
Severity: Normal Keywords:
Cc: django@…, dgouldin@…, sj@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


I have a ModelForm based on a model with two ManyToMany fields. Whenever I output the form using the as_FOO convenience methods, the ModelMultipleChoiceField widgets are placed at the end of the ouput, rather than at the top of the output, a la their position in the model.

Attachments (3)

6953.diff (7.0 KB) - added by David Gouldin 8 years ago.
modelform-m2m.diff (7.4 KB) - added by Alex Gaynor 8 years ago.
6953.2.diff (8.7 KB) - added by Matthias Kestenholz 6 years ago.

Download all attachments as: .zip

Change History (22)

comment:1 Changed 8 years ago by anonymous

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

comment:2 Changed 8 years ago by brooks.travis@…

Example Model:

class SupportTicket(models.Model):
	client = models.ManyToManyField(Client)
	call_type = models.ManyToManyField("CallType")
	priority = models.CharField(choices=PRIORITY_LEVELS, default=3, max_length=2)
	call_source = models.ForeignKey("CallSource", null=True, blank=True)
	call_description = models.TextField("Call Description", max_length=500)
	call_status = models.ForeignKey("CallStatus")
	cause = models.ForeignKey("Causes", null=True, blank=True)
	equipment_tag = models.CharField(max_length=50, null=True, blank=True)
	solution = models.TextField(max_length=500, blank=True)
	date_created = models.DateTimeField(, editable=False)
	created_by = models.ForeignKey(User, related_name='ticket_created')
	date_modified = models.DateTimeField(null=True, blank=True, editable=False)
	last_modified_by = models.ForeignKey(User, related_name='ticket_modified', null=True, blank=True)
	target_date = models.DateTimeField(null=True, blank=True)
	date_closed = models.DateTimeField(null=True, blank=True)
	closed_by = models.ForeignKey(User, related_name='ticket_closed', null=True, blank=True)
	def __unicode__(self):
		return u"%s" %
	def save(self):
			self.date_modified =
		super(SupportTicket, self).save()

Example ModelForm:

class TicketForm(forms.ModelForm):

	class Meta:
		model = SupportTicket
		exclude = ('date_created', 'created_by', 'date_modified', 'last_modified_by', 'date_closed', 'closed_by')

Example as_FOO output:

<p><label for="id_priority">Priority:</label> <select name="priority" id="id_priority">
<option value="4">LOW</option>
<option value="3" selected="selected">MEDIUM</option>
<option value="2">HIGH</option>
<option value="1">EMERGENCY</option>
<p><label for="id_call_source">Call source:</label> <select name="call_source" id="id_call_source">
<option value="" selected="selected">---------</option>
<option value="2">Phone</option>
<p><label for="id_call_description">Call Description:</label> <textarea id="id_call_description" rows="10" cols="40" name="call_description"></textarea></p>
<p><label for="id_call_status">Call status:</label> <select name="call_status" id="id_call_status">
<option value="" selected="selected">---------</option>
<option value="1">In Progress</option>
<p><label for="id_cause">Cause:</label> <select name="cause" id="id_cause">
<option value="" selected="selected">---------</option>
<p><label for="id_equipment_tag">Equipment tag:</label> <input id="id_equipment_tag" type="text" name="equipment_tag" maxlength="50" /></p>
<p><label for="id_solution">Solution:</label> <textarea id="id_solution" rows="10" cols="40" name="solution"></textarea></p>
<p><label for="id_target_date">Target date:</label> <input type="text" name="target_date" id="id_target_date" /></p>
<p><label for="id_client">Client:</label> <select multiple="multiple" name="client" id="id_client">
<option value="1">Brooks Travis</option>
</select>  Hold down "Control", or "Command" on a Mac, to select more than one.</p>
<p><label for="id_call_type">Call type:</label> <select multiple="multiple" name="call_type" id="id_call_type">
<option value="1">Hard Drive</option>
</select>  Hold down "Control", or "Command" on a Mac, to select more than one.</p>

comment:3 Changed 8 years ago by anonymous

Version: SVNnewforms-admin

comment:4 Changed 8 years ago by Karen Tracey <kmtracey@…>

Version: newforms-adminSVN

What does this have to do with newforms-admin? It was originally opened with version SVN and anonymously changed to nfa. Reverting. If there's something nfa specific about this ticket please spell it out.

comment:5 Changed 8 years ago by Eric Holscher

milestone: 1.0
Triage Stage: UnreviewedAccepted

comment:6 Changed 8 years ago by James Bennett

milestone: 1.0post-1.0

As a sort of cosmetic change, I think this can safely go post-1.0.

Changed 8 years ago by David Gouldin

Attachment: 6953.diff added

comment:7 Changed 8 years ago by David Gouldin

Has patch: set

Changed 8 years ago by Alex Gaynor

Attachment: modelform-m2m.diff added

comment:8 Changed 8 years ago by worksology

Cc: django@… added

This patch definitely fixes the problem as I was experiencing it. If the patch is truly this simple, this should have made it into 1.0. This is NOT just a cosmetic defect. The order of fields in most forms is damn important, and if the only other option is to hardcode the fields in the right order in your templates, then this seems to be a significant issue.

Thanks for the patch Alex.

comment:9 Changed 8 years ago by Alex Gaynor

Owner: changed from nobody to Alex Gaynor

comment:10 Changed 8 years ago by (none)

milestone: post-1.0

Milestone post-1.0 deleted

comment:11 Changed 8 years ago by David Gouldin

Alex, it looks like the sorted builtin was added in Python 2.4:

Are we interested in keeping 2.3 support as specified here?

comment:12 Changed 8 years ago by Alex Gaynor

Yeah, I have a branch on github with my work on this and I added the whole conditional import of sorted thing for compatibility, it's the modelform-m2m branch :)

comment:13 Changed 8 years ago by David Gouldin

Cc: dgouldin@… added

Hah! Learn something new every day ...

comment:14 Changed 7 years ago by Stephan Jaensch

I just hit this bug as well. What's holding the patch up? Seems trivial to me.

comment:15 Changed 7 years ago by Stephan Jaensch

Cc: sj@… added

comment:16 Changed 6 years ago by Matthias Kestenholz

Same patch updated for current trunk. Please test and move to ready for checkin if it works for you too.

Changed 6 years ago by Matthias Kestenholz

Attachment: 6953.2.diff added

comment:17 Changed 5 years ago by Julien Phalip

Severity: Normal
Type: Bug

comment:18 Changed 5 years ago by Julien Phalip

Triage Stage: AcceptedReady for checkin

comment:19 Changed 5 years ago by Jannis Leidel

Resolution: fixed
Status: newclosed

In [16063]:

Fixed #6953 -- Correctly sort ManyToMany fields in ModelForms. Thanks, dgouldin, mk and Alex.

Note: See TracTickets for help on using tickets.
Back to Top