如何向 Django 表单小部件添加额外的上下文
How to add additional context to a django form widget
基本的 Django CheckboxSelectMultiple
小部件允许将 label
和 value
传递给模板。我想从一个模型中添加 2 个额外的字段,但我不知道如何添加,尽管我相信它是通过子类化 get_context
我有这个模型,我想在小部件中包含 icon
和 description
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 小部件如何获取对象。
如有任何帮助,我将不胜感激 - 谢谢
这可能不是最好的解决方案,但它确实有效。
我像这样覆盖 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 }}
获取这些属性。
在 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 }}
访问模板中的哪个
如果您有一个 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 }}
这节省了从模型中添加更多信息的另一趟数据库。
基本的 Django CheckboxSelectMultiple
小部件允许将 label
和 value
传递给模板。我想从一个模型中添加 2 个额外的字段,但我不知道如何添加,尽管我相信它是通过子类化 get_context
我有这个模型,我想在小部件中包含 icon
和 description
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 小部件如何获取对象。
如有任何帮助,我将不胜感激 - 谢谢
这可能不是最好的解决方案,但它确实有效。
我像这样覆盖 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 }}
获取这些属性。
在 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 }}
如果您有一个 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 }}
这节省了从模型中添加更多信息的另一趟数据库。