41

I have an 'order' Model:

class Order(models.Model):
     date_time=models.DateTimeField()
     # other stuff

And I'm using Django ModelForm class to render a form, but I want to display date and time widgets separately. I've came up with this:

class Form(forms.ModelForm): 
    class Meta:
        model = Order
        exclude = ('date_time',)
        date = forms.DateField()
        time = forms.TimeField()

The problem is that I want to put these fields somewhere between 'other stuff'

Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
joozek
  • 2,143
  • 2
  • 21
  • 32
  • possible duplicate of [How does Django Know the Order to Render Form Fields?](http://stackoverflow.com/questions/350799/how-does-django-know-the-order-to-render-form-fields) – DrTyrsa Feb 22 '12 at 12:17

2 Answers2

69

You can use:

class Meta:
    fields = [ ..., 'date', 'time', ... ]

See the docs: http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#changing-the-order-of-fields

tread
  • 10,133
  • 17
  • 95
  • 170
Lukasz Korzybski
  • 6,689
  • 2
  • 27
  • 27
  • 12
    This is the correct answer, while I just want to mention that fields=[...] can contain user defined fields. – dspjm Apr 04 '14 at 07:53
  • Exactly, and when you try to override `__init__` calling `self.fields.keyOrder = [ ...]` instead - you will get problems (exceptions etc.). – Tomasz Gandor Apr 25 '14 at 09:37
  • 3
    As of Jan2021/Django 3.0, the documentation you've linked to doesn't feature a "changing the order of fields" section. If I use the solution you've given, Django throws a "ModelForm has no model class specified" error. – Darien Marks Jan 19 '21 at 12:54
  • As for Django 3.1 and certainly for previous versions, readonly fields are always put at last. – elsadek Dec 05 '21 at 09:45
2

Adding to Lukasz answer, in Django 2.0 the complete admin form registration with field ordering would look like the following:

models.py

class Order(models.Model):
    date_time = models.DateTimeField()
    # other fields

admin.py

class OrderForm(forms.ModelForm):
    datef = forms.DateField()
    timef = forms.TimeField()

    class Meta:
      model = Order
      exclude = ['date_time']
      fields = (
          'datef',
          'timef',
          # other fields
      )

class OrderAdmin(admin.ModelAdmin):
    form = OrderForm

admin.site.register(Order, OrderAdmin)

Note that date and time fields are defined in ModelForm class and not in Meta class.

Alex Volkov
  • 2,812
  • 23
  • 27
  • 1
    This requires all fields to be specified... is there a way to do it like how field_order works for regular forms? Where the rest of the fields are appended to the end. – bparker Feb 21 '19 at 16:32