如何在django中为选项标签添加属性?

iva*_*123 12 django admin widget options drop-down-menu

我必须将title属性添加到ModelChoiceField的选项中.这是我的管理代码:

class LocModelForm(forms.ModelForm):
        def __init__(self,*args,**kwargs):
            super(LocModelForm,self).__init__(*args,**kwargs)
            self.fields['icons'] = forms.ModelChoiceField(queryset = Photo.objects.filter(galleries__title_slug = "markers"))
            self.fields['icons'].widget.attrs['class'] = 'mydds'


        class Meta:
            model = Loc
            widgets = {
                'icons' : forms.Select(attrs={'id':'mydds'}), 
                }

        class Media:
            css = {
                "all":("/media/css/dd.css",)
                }
            js=(
                '/media/js/dd.js',
                )

class LocAdmin(admin.ModelAdmin):
    form = LocModelForm
Run Code Online (Sandbox Code Playgroud)

我可以添加任何属性来选择小部件,但我不知道如何向选项标签添加属性.任何的想法 ?

Cat*_*lus 18

首先,不要修改字段__init__,如果要覆盖窗口小部件使用Meta内部类,如果要覆盖窗体字段,请以普通(非模型)形式声明它们.

如果Select窗口小部件没有按照你想要的那样做,那么只需创建自己的部件.原始窗口小部件使用render_option方法为单个选项获取HTML表示 - 创建子类,覆盖它,并添加任何您想要的内容.

class MySelect(forms.Select):
    def render_option(self, selected_choices, option_value, option_label):
        # look at the original for something to start with
        return u'<option whatever>...</option>'

class LocModelForm(forms.ModelForm):
    icons = forms.ModelChoiceField(
        queryset = Photo.objects.filter(galleries__title_slug = "markers"),
        widget = MySelect(attrs = {'id': 'mydds'})
    )

    class Meta:
        # ...
        # note that if you override the entire field, you don't have to override
        # the widget here
    class Media:
        # ...
Run Code Online (Sandbox Code Playgroud)

  • 是否有任何特殊原因可以在`Meta`内部类而不是`__init__`方法中修改字段?并且相同的推理是否适用于修改/添加字段的窗口小部件属性? (4认同)
  • render_option 在 1.11 btw https://docs.djangoproject.com/en/2.1/releases/1.11/#changes-due-to-the-introduction-of-template-based-widget-rendering 中被删除 (2认同)

kay*_*yoz 5

我遇到了类似的问题,我需要在其中动态地向每个选项添加自定义属性。但是在Django 2.0中,html呈现已移至Widget基类中,因此修改render_option不再有效。这是为我工作的解决方案:

from django import forms

class CustomSelect(forms.Select):
    def __init__(self, *args, **kwargs):
        self.src = kwargs.pop('src', {})
        super().__init__(*args, **kwargs)

    def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
        options = super(CustomSelect, self).create_option(name, value, label, selected, index, subindex=None, attrs=None)
        for k, v in self.src.items():
            options['attrs'][k] = v[options['value']]
        return options

class CustomForm(forms.Form):
    def __init__(self, *args, **kwargs):
        src = kwargs.pop('src', {})
        choices = kwargs.pop('choices', ())
        super().__init__(*args, **kwargs)
        if choices:
            self.fields['custom_field'].widget = CustomSelect(attrs={'class': 'some-class'}, src=src, choices=choices)

    custom_field = forms.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

然后在视图中渲染上下文,{'form': CustomForm(choices=choices, src=src)}其中src字典是这样的:{'attr-name': {'option_value': 'attr_value'}}


p14*_*14z 5

如果你想使用实例来设置属性值,这里有一个解决方案。

class IconSelectWidget(forms.Select):
    def create_option(self, name, value, *args, **kwargs):
        option = super().create_option(name, value, *args, **kwargs)
        if value:
            icon = self.choices.queryset.get(pk=value)  # get icon instance
            option['attrs']['title'] = icon.title  # set option attribute
        return option

class LocModelForm(forms.ModelForm):
    icons = forms.ModelChoiceField(
        queryset=Photo.objects.filter(galleries__title_slug='markers'),
        widget=IconSelectWidget
    )
Run Code Online (Sandbox Code Playgroud)