rob*_*ter 3 django django-forms django-widget
假设你有某个型号
class MyModel(models.Model):
Name = models.CharField(max_length=64)
Run Code Online (Sandbox Code Playgroud)
以及您用于创作的随附表格
class CreateMyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['name']
Run Code Online (Sandbox Code Playgroud)
在正常情况下,当在模板中呈现表单时,我通常会循环遍历模板中的字段
{%for field in form%}
{{field}}
{%endfor%}
Run Code Online (Sandbox Code Playgroud)
当需要自定义样式时,我通常不得不将我的<div>s 和s 放入该循环中,并在子类中<span>指定基本小部件及其。attrsMeta
浏览有关该主题的Django 文档,我明白似乎我必须使用Media子类才能使所有操作发生在 的widgets属性中Meta,但我就是无法理解它。
假设我有一个模板,其中TextInput需要呈现表单,如下模板所示:
<div class="form-group input-group">
<span class="input-group-addon">Name</span>
<input type="text" name="name" class="form-control" placeholder="MyModel Name">
</div>
Run Code Online (Sandbox Code Playgroud)
我如何创建一个小部件,以便我可以通过使用以下方法获得相同的结果:
class CreateMyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['name']
widgets={'name':MyWidget(addon="Name",placeholder="MyModel Name")}
Run Code Online (Sandbox Code Playgroud)
我知道占位符是我可以放入 的attrs初始化中的东西TextInput,但插件(或本例中的父 div)不是或至少据我所知不是
我为一个很长的问题道歉,我只是觉得我需要彻底解释这个问题,因为它已经困扰我一段时间了......
我们可以像下面这样做。
from django import forms
from django.template import loader
from django.utils.safestring import mark_safe
class MyWidget(forms.Widget):
template_name = 'widget_template.html'
def get_context(self, name, value, attrs=None):
return {'widget': {
'name': name,
'value': value,
}}
def render(self, name, value, attrs=None):
context = self.get_context(name, value, attrs)
template = loader.get_template(self.template_name).render(context)
return mark_safe(template)
Run Code Online (Sandbox Code Playgroud)
<div class="form-group input-group">
<span class="input-group-addon">Name</span>
<input type="text" class="form-control" id="mywidget-{{ widget.name }}" name="{{ widget.name }}" />
</div>
Run Code Online (Sandbox Code Playgroud)