Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'to_field_name' argument on a ModelChoiceField() doesn't seem to be working

Well, pretty much what it says in the title.

I'm creating a ModelChoiceField() in one of my Forms, like so:

class FormCreatePlace(forms.ModelForm):
    (...)
    category = forms.ModelChoiceField(queryset=Category.objects.all(), to_field_name='name')
    (...)

The Category model is defined like so:

class Category(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=40)

And yet the field itself on the HTML form insists on displaying the primary keys (a series of UUIDs) as the choices.

What am I doing wrong?

like image 810
flatterino Avatar asked Jan 03 '23 17:01

flatterino


1 Answers

The to_field_name is used to change the value of the options, not the displayed text

The easiest way to change the displayed text is to change the __str__ method on your model to return the name field:

class Category(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

However, that will affect how the categories are displayed elsewhere. If you don't want to do that, you can subclass ModelChoiceField and override label_from_instance.

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

Then use your choice field in the form.

class FormCreatePlace(forms.ModelForm):
    (...)
    category = forms.MyModelChoiceField(queryset=Category.objects.all())

See the ModelChoiceField docs for more info.

like image 100
Alasdair Avatar answered Jan 05 '23 15:01

Alasdair