Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django RadioSelect小部件,添加其他信息_Django_Django Forms_Django Crispy Forms - Fatal编程技术网

Django RadioSelect小部件,添加其他信息

Django RadioSelect小部件,添加其他信息,django,django-forms,django-crispy-forms,Django,Django Forms,Django Crispy Forms,我有这个简化的模型和形式: 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 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表单,如下所示:

(x) Book1
( ) Book2
( ) Book3
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} €)"
<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>
我的问题是,我如何在RadioSelect表单中添加价格,因为它是可见的。 它应该出现在书名之后,理想情况下甚至是以不同的字体出现,这是我在引导类上设置的(例如“text primary”)(这不是强制性的)

我知道我可以在模型中返回名称和价格,如

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表单,但找不到解决方案。

您可以使用
.label\u from\u instance

从:

将调用模型的
\uuu str\uu()
方法来生成对象的字符串表示形式,以便在字段的选择中使用。若要提供自定义表示,请将
modelcoocefield
子类化,并覆盖
label\u from\u instance

您可以定义一个函数,为您提供所需的表示形式,然后在字段上设置
.label\u from\u instance

您的
书单
如下所示:

(x) Book1
( ) Book2
( ) Book3
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} €)"
<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>
要在标签上应用CSS,请添加HTML。除了使用
style='…'
之外,还可以使用类,使其与引导一起工作

self.fields["Field"].label_from_instance = lambda item: f"{item} <span style='color:red;'>({item.price} €)</span>"

过滤器是必需的,这样你的HTML就不会被转义。

如果你不能连接标签,我相信信息不在你的模型中或者更接近的东西中。。。所以我相信挑战仍在形式上。。。可以使用ajax吗?从端点(URL)加载额外数据并将其连接到客户端的javascript?谢谢你的想法,但我对ajax/javascript不太熟悉。也许我必须把标签连在一起,在以后的某个时候去掉价格,这是一个有点黑客的Solution imo。额外的信息在哪里?在您的数据库中,或者您必须从其他站点(或外部服务)获取它?非常感谢!您能否详细介绍一下这个lambda函数以及项来自何处?lambda函数在呈现模板时获取
Book
实例,以获取标签。你可以使用一个普通的函数和一个参数来代替lambda,它只需要是可调用的,然后返回你想要的标签在呈现的模板中的样子。您推荐未来的fstring,还是有其他方法为python 3.5编写它?我添加了一种不使用f-string的方法,您也可以使用
.format()
,但我发现f-string比其他方法好得多。这对python 3.5和之前的版本也适用:lambda obj:“%s+(++%s€”)”%(obj,obj.price)