Using a specific Model Field for Choices

I have a CreateView that renders the following form:

class PackageForm(forms.ModelForm):
    class Meta:
        """Meta Class for Form"""
    
        model = Package
        fields = "__all__"
        labels = {"servicefk": "Service"}

The form creates a model instance (Package). The Package model connects to Service model (see below) viia a foreign key (servicefk):

class Service(models.Model):
    name = models.TextField()
    abbreviation = models.CharField(max_length=255)
    
    def __str__(self):
        """A textual name for terminal outputs"""
        
        return self.abbreviation

The view renders fine except for one thing: It renders the abbreviation field as choices for the Select input element. I want the full “name” field instead. Apparently, django is using the output of the __str__() to construct the choices. What is the quickest way to list the name field instead … without altering __str__()? Please don’t send me to the docs … I am experiencing a mental block

You can define a custom ModelField for the servicefk field. E.g.:

from django.forms import ModelChoiceField

class ServiceModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.name

Then in your ModelForm, define:

class  PackageForm(forms.ModelForm):
    class Meta:
        """Meta Class for Form"""
    
        model = Package
        fields = "__all__"
        field_classes = {"servicefk": ServiceModelChoiceField}
        labels = {"servicefk": "Service"}
1 Like

That was amazing! Where can I find documentation on ModelChoiceFields and field_classes? I would like to know more about those.

I realized you meant "field_classes’ when your sample didn’t work. It worked perfectly after I adapted it.

Sorry for the typo error. I corrected my answer.

You can find information about ModelForm’s fields overrides here (Creating forms from models | Django documentation | Django) and ModelChoiceField here (Form fields | Django documentation | Django) where it is explained that

The str() 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.

1 Like