Skip to content
Advertisement

ordering modelchoicefield in django loses formatting

I wanted to order a list in my form view, and found this post here:

How do I specify an order of values in drop-down list in a Django ModelForm?

So I edited my code and added the line specialty = forms.ModelChoiceField(queryset ='...')

So then I reload the form and the widget is all smoshed and funky looking. I checked the html code and the specialties are indeed in the right order! But it misses the widget definition lower adding the form-control class. I am not sure why. if I remove the line specialty = form.ModelChoiceField then everything looks great aside from the dropdown not being in the right order (alphabetical by name field)

Not sure why it is missing that widget definition and attaching the class form-control or the tabindex even. Guessing the specialty = forms.ModelChoiceField is overriding it somehow?

class ProviderForm(forms.ModelForm):

  specialty = forms.ModelChoiceField(queryset = Specialty.objects.order_by('name'))   #added this

  def __init__(self, *args, **kwargs):
    super(ProviderForm, self).__init__(*args, **kwargs)
    self.helper = FormHelper()  
    self.helper.form_class = 'form-horizontal'
    self.helper.label_class = 'col-md-6'
    self.helper.field_class = 'col-md-6'
    self.fields['ptan'].required = False
    self.helper.layout = Layout(
        Field('...'),
        Field('specialty'),
        FormActions(
          Submit('save', 'Save'),
          Button('cancel', 'Cancel'),
          Button('terminate', 'Terminate', css_class="btn-danger"),
        ),
    )
 
  class Meta:
    
    model=Provider
    fields = (
      '...',
      'specialty'
    ) 


    widgets = {
    
      'specialty':Select(attrs={
          'tabindex':'4',
          'class':'form-control'
      }),
      
    }

Advertisement

Answer

This is explained in the documentation, inside a big note:

When you explicitly instantiate a form field like this, it is important to understand how ModelForm and regular Form are related.

ModelForm is a regular Form which can automatically generate certain fields. The fields that are automatically generated depend on the content of the Meta class and on which fields have already been defined declaratively. Basically, ModelForm will only generate fields that are missing from the form, or in other words, fields that weren’t defined declaratively.

Fields defined declaratively are left as-is, therefore any customizations made to Meta attributes such as widgets, labels, help_texts, or error_messages are ignored; these only apply to fields that are generated automatically.

So, just add the widget argument to your declarative field:

specialty = forms.ModelChoiceField(
    queryset = Specialty.objects.order_by('name'),
    widget = Select(attrs={
          'tabindex':'4',
          'class':'form-control'
      })
)
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement