如何将其他上下文添加到Django表单小部件

时间:2019-06-26 11:34:54

标签: django django-forms django-widget

基本的Django CheckboxSelectMultiple小部件允许将labelvalue传递到模板。我想从模型中添加2个其他字段,但是我无法确定具体方法,尽管我相信这是通过对get_context

进行子类化来实现的

我有这个模型,我想在小部件中包含icondescription

class AddOnItem(models.Model):
    name = models.CharField(
        verbose_name = 'AddOn Title',
        max_length = 50
    )
    description = models.CharField(
        verbose_name = 'Description',
        max_length = 255
    )
    icon = models.FileField(upload_to="addon_icons/", blank=True, null=True)
    active = models.BooleanField(default=False)

在我的表单中,我指定了此小部件

class JobPostWizardForm1(forms.ModelForm):
    class Meta:
        model = Job
        fields = [
            ...,
            'addons'
            ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        ...

        self.fields['addons'].widget = AddOnCheckboxSelectMultiple()
        self.fields['addons'].queryset = AddOnItem.objects.filter(active=True)

并且我将CheckboxSelectMultiple小部件的子类化为

class AddOnCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
    template_name = 'jobboard/widgets/addon_checkbox_select.html'
    option_template_name = 'jobboard/widgets/addon_checkbox_option.html'

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value,attrs)
        return context

很明显,这暂时什么也没做,但是我想添加

context['icon'] = obj.icon

但是我不知道该怎么做。也就是说,我不了解Django小部件如何获取对象。

非常感谢您能提供的任何帮助-谢谢

3 个答案:

答案 0 :(得分:0)

这可能不是最佳解决方案,但它可以工作。

我像这样create_option的子类:

def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
    ctx = super().create_option(name, value, label, selected, index, subindex=subindex, attrs=attrs)
    obj = AddOnItem.objects.get(id=int(value))
    ctx['icon'] = obj.icon
    ctx['description'] = obj.description
    ctx['price'] = obj.price

    return ctx

然后我可以在模板中使用{{ widget.field_name }}获取这些属性

答案 1 :(得分:0)

在使用MultiWidget的情况下,类似于@HenryM的答案,可以将get_context方法子类化并分配值,如下所示:

def get_context(self, name, value, attrs):
    context = super().get_context(name, value, attrs)
    context["some_field"] = "some_value"
    return context

{{ some_field }}可以访问哪个模板

答案 2 :(得分:0)

如果您有一个带有 ModelForm (ForeignKey) 的 ModelChoiceField,您可以像这样在自定义小部件中设置额外的上下文:

class CustomRadioSelect(forms.RadioSelect):
    option_template_name = "widgets/test.html"

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)
        for option in context['widget']['optgroups']:
            _, opts, _ = option
            for opt in opts:
                opt['other_attributes'] = opt['value'].instance.other_attributes
        return context

在这个例子中,我的模型有一个属性 other_attributes,我想在我的小部件中访问它。

然后在我的 option_template 中:

{{ widget.other_attributes }}

这会保存另一次访问数据库以从模型添加更多信息。

相关问题