Django-动态添加Css类以形成字段选项

Django-动态添加Css类以形成字段选项,django,django-forms,Django,Django Forms,这可能是非常简单的事情之一,我只是错过了,或者可能非常困难。还不确定,但我知道我还没有找到简单的方法 我有一个modelmultipechoicefield的扩展,我想把一些CSS类放在各个选项行上——我想让每一行从它所选择的对象中获得它的类。具体地说,我正在选择志愿者的机会,并且我想按天对它们进行颜色编码。一个给定的事件(例如,一个志愿者机会)知道它什么时候开始,所以我可以从事件中获取日期,显然我可以在它上面打一个@property,让它吐出一个字符串,比如“friday”,但我看不到如何要求

这可能是非常简单的事情之一,我只是错过了,或者可能非常困难。还不确定,但我知道我还没有找到简单的方法

我有一个modelmultipechoicefield的扩展,我想把一些CSS类放在各个选项行上——我想让每一行从它所选择的对象中获得它的类。具体地说,我正在选择志愿者的机会,并且我想按天对它们进行颜色编码。一个给定的事件(例如,一个志愿者机会)知道它什么时候开始,所以我可以从事件中获取日期,显然我可以在它上面打一个@property,让它吐出一个字符串,比如“friday”,但我看不到如何要求字段组织自己,以便每个选项都通过引用该属性来添加一个类


我也尝试过用这种样式来编写模板,但是这变得非常痛苦,效果也不太好,而且可能会成为维护过程中的一个痛点,所以如果可以的话,我想做得更进一步

我不得不定制很多django表单,我感觉到了你的痛苦。我想我明白你想做什么,我相信有一个解决办法

django.forms.models
中,为
modelmultipechoicefield
定义的小部件是
SelectMultiple
,它位于
django.forms.widgets
中。这负责呈现整个小部件,但是如果查看小部件的
render
方法内部,它实际上是将
render\u options
的结果包装在
HTML元素内部

render\u options
方法位于父
Select
小部件上,该小部件依次调用同一类上的
render\u选项
方法。这是呈现每个
元素的实际HTML的地方,您可以在这里连接以添加HTML属性。这里为您提供了
选项\u value
属性,因此您可以检查任何需要检查的内容,并确定希望在HTML中包含的属性。您将负责返回HTML,这样您就可以复制/修改函数并根据需要进行修改(这就是为什么这很痛苦的原因)。请参阅github上的以获取参考

您必须为此定义一个小部件子类
SelectMultiple
,并将其作为小部件分配给您的字段;要做到这一点,请执行以下操作(取决于您是否需要小部件实例的任何运行时参数):


所以,是的,这是相当黑客,想知道是否有一个更简单的方法来做到这一点。如果有,我很高兴知道,因为我们不得不在工作场所的一些地方这样做,而且每次都感觉脏兮兮的(将标记与功能混合在一起不是我的最爱)。您可以完全覆盖小部件的
render()
方法来执行自定义操作,但这可能是启动并运行小部件所能做的最小更改。

必须自定义许多django表单,我感到您的痛苦。我想我明白你想做什么,我相信有一个解决办法

django.forms.models
中,为
modelmultipechoicefield
定义的小部件是
SelectMultiple
,它位于
django.forms.widgets
中。这负责呈现整个小部件,但是如果查看小部件的
render
方法内部,它实际上是将
render\u options
的结果包装在
HTML元素内部

render\u options
方法位于父
Select
小部件上,该小部件依次调用同一类上的
render\u选项
方法。这是呈现每个
元素的实际HTML的地方,您可以在这里连接以添加HTML属性。这里为您提供了
选项\u value
属性,因此您可以检查任何需要检查的内容,并确定希望在HTML中包含的属性。您将负责返回HTML,这样您就可以复制/修改函数并根据需要进行修改(这就是为什么这很痛苦的原因)。请参阅github上的以获取参考

您必须为此定义一个小部件子类
SelectMultiple
,并将其作为小部件分配给您的字段;要做到这一点,请执行以下操作(取决于您是否需要小部件实例的任何运行时参数):


所以,是的,这是相当黑客,想知道是否有一个更简单的方法来做到这一点。如果有,我很高兴知道,因为我们不得不在工作场所的一些地方这样做,而且每次都感觉脏兮兮的(将标记与功能混合在一起不是我的最爱)。您可以完全覆盖小部件的
render()
方法来执行自定义操作,但这可能是您为使其启动并运行所能做的最小更改。

请注意,负责呈现的是小部件,而不是字段。请注意,是小部件,而不是字段,它负责渲染。
class MyWidgetSubclass(SelectMultiple):

    def render_option(selected_choices, option_value, option_label):

        my_fancy_new_html_for_the_option = ...
        ... your code here ...
        return my_fancy_new_html_for_the_option

class MyForm(Form):

    my_field = ModelMultipleChoiceField(widget=MyWidgetSubclass)

    # or

    def __init__(*args, **kwargs):  # Not the real params, of course

       super(MyForm, self).__init__(*args, **kwargs)

       # You'll probably need to pass arguments to the instantiation.
       self.fields['my_field'].widget = MyWidgetSubclass()