Code

Opened 6 years ago

Closed 3 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
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:

Description

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 dgouldin 6 years ago.
modelform-m2m.diff (7.4 KB) - added by Alex 5 years ago.
6953.2.diff (8.7 KB) - added by mk 3 years ago.

Download all attachments as: .zip

Change History (22)

comment:1 Changed 6 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 6 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(default=datetime.datetime.now, 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" % self.id
	
	def save(self):
		if self.id:
			self.date_modified = datetime.datetime.now()
		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>
</select></p>
<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>
</select></p>
<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>
</select></p>
<p><label for="id_cause">Cause:</label> <select name="cause" id="id_cause">
<option value="" selected="selected">---------</option>
</select></p>
<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 6 years ago by anonymous

  • Version changed from SVN to newforms-admin

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

  • Version changed from newforms-admin to SVN

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 6 years ago by ericholscher

  • milestone set to 1.0
  • Triage Stage changed from Unreviewed to Accepted

comment:6 Changed 6 years ago by ubernostrum

  • milestone changed from 1.0 to post-1.0

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

Changed 6 years ago by dgouldin

comment:7 Changed 6 years ago by dgouldin

  • Has patch set

Changed 5 years ago by Alex

comment:8 Changed 5 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 5 years ago by Alex

  • Owner changed from nobody to Alex

comment:10 Changed 5 years ago by anonymous

  • milestone post-1.0 deleted

Milestone post-1.0 deleted

comment:11 Changed 5 years ago by dgouldin

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

http://docs.python.org/library/functions.html#sorted

Are we interested in keeping 2.3 support as specified here?

http://docs.djangoproject.com/en/dev/topics/install/#install-python

comment:12 Changed 5 years ago by Alex

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 5 years ago by dgouldin

  • Cc dgouldin@… added

Hah! Learn something new every day ...

comment:14 Changed 4 years ago by sjaensch

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

comment:15 Changed 4 years ago by sjaensch

  • Cc sj@… added

comment:16 Changed 3 years ago by mk

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

Changed 3 years ago by mk

comment:17 Changed 3 years ago by julien

  • Severity set to Normal
  • Type set to Bug

comment:18 Changed 3 years ago by julien

  • Triage Stage changed from Accepted to Ready for checkin

comment:19 Changed 3 years ago by jezdez

  • Resolution set to fixed
  • Status changed from new to closed

In [16063]:

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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.