Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling Django ModelForm output

I've got a Model in Django, example code below (not my actual code):

class Department(models.Model):
    name = models.CharField(max_length=100)
    abbreviation = models.CharField(max_length=4)

Let's say I do the following in the Django shell:

>>> Department(name='Computer Science',abbreviation='C S ').save()
>>> Department(name='Mathematics',abbreviation='MATH').save()
>>> Department(name='Anthropology',abbreviation='ANTH').save()

I now have those four departments stored in my database. Say we have another class, Course, which belongs to a Department:

class Course(models.Model):
    department = models.ForeignKey('Department')
    number = models.IntegerField()

class CourseForm(ModelForm):
    class Meta:
        model = Course

If I render the ModelForm object directly in a template by just referncing a variable, say form, which got passed down, the Departments appear in a drop-down box (an HTML select box). So far so good.

The problem is: the items in the select box are sorted by ID. So they appear as:

  1. Computer Science
  2. Mathematics
  3. Anthropology

But, I want them sorted alphabetically, i.e.

  1. Anthropology
  2. Computer Science
  3. Mathematics

How can I change the way these items are sorted in the ModelForm code, or in the Model code, rather than in the template?

And in general, how can I customize the way a particular field or widget works when generated by a ModelForm?

like image 754
Glen Balliet Avatar asked Aug 14 '09 17:08

Glen Balliet


2 Answers

How can I change the way these items are sorted in the ModelForm code, or in the Model code, rather than in the template?

One thing you can do is add an ordering meta option. You do this by adding a Meta inner class to a class, with the ordering attribute specified:

class Department(models.Model):
    name = models.CharField(max_length=100)
    abbreviation = models.CharField(max_length=4)

    class Meta:
        ordering = ["name"]

Note that this changes default ordering for Department models (not just when used in a form).

And in general, how can I customize the way a particular field or widget works when generated by a ModelForm?

You'll want to read the Django docs about ModelForm and built-in form fields. In particular, pay attention to the optional widget attribute, which allows you to change a form field's widget. The difference types of widgets are described here.

like image 113
mipadi Avatar answered Sep 23 '22 23:09

mipadi


mipadi has shown you how to modify the ordering for your Department model, and this is reflected in the form widget.

However, if you only wanted to change the ordering for that widget, and leave the model's default ordering as something else, you could do this:

class CourseForm(ModelForm):
    department = forms.ModelChoiceField(
                           queryset=Department.objects.order_by('name'))

    class Meta:
        model = Course
like image 44
Daniel Roseman Avatar answered Sep 23 '22 23:09

Daniel Roseman