我有这个简化的模型和表格:
class Books(models.Model):
name = models.CharField(max_length=500)
price = models.DecimalField(max_digits=6, decimal_places=2)
default = models.BooleanField(default=False)
def __str__(self):
return self.name
class BookForm(forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['Field'] = forms.ModelChoiceField(queryset=None, empty_label=None, widget=forms.RadioSelect)
self.fields['Field'].queryset = Books.objects.all()
self.fields['Field'].initial = Books.objects.filter(default=True).first()
这将产生一个RadioSelect-Form,如下所示:
(x) Book1
( ) Book2
( ) Book3
我的问题是,如何在RadioSelect表单中添加价格,使其可见。 它应该出现在书名之后,最好还是以其他字体出现,这是我在引导程序类(例如“ text-primary”)上设置的(这不是强制性的)
(x) Book1 (10 €)
( ) Book2 (20 €)
( ) Book3 (30 €)
我知道我可以在模型中返回名称和价格,例如
class Books(models.Model):
name = models.CharField(max_length=500)
price = models.DecimalField(max_digits=6, decimal_places=2)
default = models.BooleanField(default=False)
def __str__(self):
return '%s (%s €)' % (self.value, str(self.price))
但是由于其他原因,我无法做到这一点。我只需要返回名字。还有其他方法吗?
我什至阅读了django-crispy-forms,但找不到解决方法。
答案 0 :(得分:2)
您可以使用.label_from_instance
。
将调用模型的
__str__()
方法来生成对象的字符串表示形式,以供在字段的选择中使用。要提供自定义表示,请子类ModelChoiceField
并覆盖label_from_instance
。
您可以定义一个函数,该函数为您提供所需的表示形式,然后在字段中设置.label_from_instance
。
您的BookForm
如下所示:
class BookForm(forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['Field'] = forms.ModelChoiceField(queryset=None, empty_label=None, widget=forms.RadioSelect)
self.fields['Field'].queryset = Books.objects.all()
self.fields['Field'].initial = Books.objects.filter(default=True).first()
# customize how your option is rendered in the template
self.fields["Field"].label_from_instance = lambda item: f"{item} ({item.price} €)"
要在标签上应用CSS,请添加HTML。除了使用style='...'
之外,您还可以使用类,使其与Bootstrap一起使用。
self.fields["Field"].label_from_instance = lambda item: f"{item} <span style='color:red;'>({item.price} €)</span>"
对于3.7之前的Python版本:
self.fields["Field"].label_from_instance = lambda item: str(item) + "<span style='color:red;'>(" + str(item.price) + " €)</span>"
然后像这样在模板中呈现表单:
<form action="{% url 'books' %}" method="post">
{% csrf_token %}
{% for hidden_field in form.hidden_fields %}
{{ hidden_field }}
{% endfor %}
<ul>
{% for choice in form.Field %}
<li>{{ choice.choice_label|safe }}</li>
{% endfor %}
</ul>
<input class="btn btn-dark" type="submit" value="Submit">
</form>
遍历您的字段的选择,然后可以使用以下方法获得自定义标签:
{{ choice.choice_label|safe }}
需要safe
过滤器,这样您的HTML才会转义。