In my Django app, I have this form:
from django import forms
from main.models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['picture']
widgets = {
'picture': forms.RadioSelect(),
}
By default, the labels of the picture field within the template are generated according to the __str__() method of the Picture model. That's because the picture field on my Profile model is actually a ForeignKey field to a Picture model.
However, the value returned by that __str__() method doesn't make much sense in this particular template, and changing it is not possible because it's being used elsewhere.
Therefore, is there a way I might change the default labels for the picture field of my ProfileForm? For instance, changing from the __str__()'s default picture.src ' (' picture.description ')' to something like picture.description only?
I have checked what the docs had to say regarding the label_from_instance, but I didn't understand how to apply it. In fact, I couldn't even understand if that would be a solution for this case.
Some similiar questions here on Stack Overflow also mentioned that link of the docs, but the questions's forms were slightly different than mine, and I ended up not understanding them either.
CodePudding user response:
If you want to use label_from_instance, you should make a specific widget with:
class PictureField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.description
class ProfileForm(forms.ModelForm):
picture = PictureField(Picture.objects)
class Meta:
model = Profile
On another hand, you can use your code and in init function of your form to change the choices attribute of the picture field
CodePudding user response:
It turns out I didn't need to use label_from_instance. I just needed to create a subclass of django.forms.RadioSelect and override its create_option() method, setting the label by giving option['label'] the value I'd like, just like this:
from django import forms
from main.models import Profile
class PictureRadioSelect(forms.RadioSelect):
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
option = super().create_option(name, value, label, selected, index, subindex, attrs)
option['label'] = value.instance.description
return option
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['picture']
widgets = {
'picture': PictureRadioSelect(),
}
This section of the docs explains this in greater detail. It actually describes how to override django.forms.Select options, but I tested it with django.forms.RadioSelect and it ran as expected.
