Override the template of a widget and pass values to it with Django 4.0
Question:
I am creating a simple app to do product reviews.
I have a Product, Manufacturer and Review models which I will now summarize
class Manufacturer(models.Model):
name = models.CharField()
class Product(models.Model):
name = models.CharField()
manufacturere = models.ForeignKey(Manufacturer)
class Review(models.Model):
title = CharField()
product = models.ForeignKey(Product)
I created a ModelForm to create the review.
So far I was only able to create a custom widget with an overridden template.
class CustomSelectWidget(forms.widgets.Select):
option_template_name = 'widgets/select_option.html'
class NewReviewForm(forms.ModelForm):
review = forms.ModelMultipleChoiceField(
queryset = Review.objects.none(),
widget = CustomSelectWidget(),
)
class Meta:
model = Review
fields = '__all__'
The form view is a normal function based view.
The review field is rendered with a list of products in a <select>.What I want to do is change the text inside <option> to make it so that the manufacturer’s name is also there.
IMPORTANT: I have to take the manufacturer’s name from the respective Object, I can’t just insert it into the Product name field.
ES:
what I have now
- Geforce RTX2080
- MAXSUN AMD Radeon RX 550
- Arca770
the goal
- NVIDIA – Geforce RTX2080
- AMD – MAXSUN Radeon RX 550
- INTEL – Arca770
Answers:
You can override create_option
in the widget:
class CustomSelectWidget(forms.widgets.Select):
option_template_name = 'widgets/select_option.html'
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
label = f"{value.instance.product.name} {value.instance.title}"
return super().create_option(name, value, label, selected, index, subindex, attrs)
I am creating a simple app to do product reviews.
I have a Product, Manufacturer and Review models which I will now summarize
class Manufacturer(models.Model):
name = models.CharField()
class Product(models.Model):
name = models.CharField()
manufacturere = models.ForeignKey(Manufacturer)
class Review(models.Model):
title = CharField()
product = models.ForeignKey(Product)
I created a ModelForm to create the review.
So far I was only able to create a custom widget with an overridden template.
class CustomSelectWidget(forms.widgets.Select):
option_template_name = 'widgets/select_option.html'
class NewReviewForm(forms.ModelForm):
review = forms.ModelMultipleChoiceField(
queryset = Review.objects.none(),
widget = CustomSelectWidget(),
)
class Meta:
model = Review
fields = '__all__'
The form view is a normal function based view.
The review field is rendered with a list of products in a <select>.What I want to do is change the text inside <option> to make it so that the manufacturer’s name is also there.
IMPORTANT: I have to take the manufacturer’s name from the respective Object, I can’t just insert it into the Product name field.
ES:
what I have now
- Geforce RTX2080
- MAXSUN AMD Radeon RX 550
- Arca770
the goal
- NVIDIA – Geforce RTX2080
- AMD – MAXSUN Radeon RX 550
- INTEL – Arca770
You can override create_option
in the widget:
class CustomSelectWidget(forms.widgets.Select):
option_template_name = 'widgets/select_option.html'
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
label = f"{value.instance.product.name} {value.instance.title}"
return super().create_option(name, value, label, selected, index, subindex, attrs)