How to choose the value and label from Django ModelChoiceField queryset

17,369

Solution 1

In your Person model add:

def __unicode__(self):
    return u'{0}'.format(self.lname)

If you are using Python 3, then define __str__ instead of __unicode__.

def __str__(self):
    return u'{0}'.format(self.lname)

Solution 2

You can just add a call to label_from_instance in the init of Form ie

by adding something like

class TestForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(TestForm, self).__init__(*args, **kwargs)

        self.fields['field_name'].label_from_instance = self.label_from_instance

    @staticmethod
    def label_from_instance(obj):
        return "My Field name %s" % obj.name

Solution 3

From the Django docs:

https://docs.djangoproject.com/en/dev/ref/forms/fields/#django.forms.ModelChoiceField

The __unicode__ (__str__ on Python 3) method of the model will be called to generate string representations of the objects for use in the field’s choices; to provide customized representations, subclass ModelChoiceField and override label_from_instance. This method will receive a model object, and should return a string suitable for representing it. For example:

from django.forms import ModelChoiceField

class MyModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return "My Object #%i" % obj.id

So, you can do that, or override __str__ on your model class to return the last name.

Solution 4

You can overwrite label_from_instance method of the ModelChoiceField instance to your custom method. You can do it inside the __init__ method of the form

class FooForm(forms.Form):
    person =  forms.ModelChoiceField(queryset=Person.objects.filter(is_active=True).order_by('id'), required=False)
    age = forms.IntegerField(min_value=18, max_value=99, required=False)

    def __init__(self, *args, **kwargs):
        super(FooForm, self).__init__(*args, **kwargs)

        self.fields['person'].label_from_instance = lambda instance: instance.name
Share:
17,369
helloworld2013
Author by

helloworld2013

Updated on June 14, 2022

Comments

  • helloworld2013
    helloworld2013 almost 2 years

    I was trying to create a django form and one of my field contain a ModelChoiceField

    class FooForm(forms.Form):
    
        person =  forms.ModelChoiceField(queryset=Person.objects.filter(is_active=True).order_by('id'), required=False)
        age = forms.IntegerField(min_value=18, max_value=99, required=False)
    

    When I try the code above what it return as an html ouput is

    <option value="1">Person object</option>
    

    on my Person Model I have the fields "id, fname, lname, is_active" . Is it possible to specify that my dropdown option will use "id" as the value and "lname" as the label? The expected html should be

    <option value="1">My Last Name</option>
    

    Thanks in advance!