Nic*_*ner 52 python forms django
我很难找到有关如何编写自定义小部件的文档.
我的问题是:
谢谢.
And*_*Dog 48
你说得对,Django没有提供有关这个特定主题的文档.我建议你看看内置的小部件django.forms.widgets(我将从下面的模块中引用类).
如果我构建自定义窗口小部件,它是否可以等效地用于管理界面或普通表单?
管理员会覆盖一些小部件(请参阅参考资料django.contrib.admin.options.FORMFIELD_FOR_DBFIELD_DEFAULTS).您可以继承子类ModelAdmin并更改formfield_overrides属性,但我从未做过任何事情,ModelAdmin所以我在这里无法帮助...
如果我想允许用户编辑项目列表,我应该将哪个小部件子类化?我需要覆盖/实现哪些小部件方法?
您的窗口小部件可能与默认窗口小部件没有任何共同之处(Select如果有的话?).子类来自Widget和如果你发现内置的任何常见模式,你仍然可以在以后更改它.
实现以下方法:
render(self, name, value, attrs=None, renderer=None)
查看Input.render一个简单的例子.它还支持HTML中包含的用户定义属性.您可能还想添加"id"属性,请参阅MultipleHiddenInput.render如何执行此操作.不要忘记mark_safe直接输出HTML时使用.如果您有一个相当复杂的小部件,则可以使用模板渲染(示例).
_has_changed(self, initial, data)
可选的.在admin中用于记录有关更改内容的消息.
什么小部件方法负责从用户的输入回到数据模型?
这与小部件无关 - Django无法知道在先前的请求中使用了哪个小部件.它只能使用从表单发送的表单(POST)数据.因此,field方法Field.to_python用于将输入转换为Python数据类型(ValidationError如果输入无效,则可能会引发).
Wto*_*wer 22
除了其他答案,这是自定义小部件的一个小代码示例:
widgets.py:
from django.forms.widgets import Widget
from django.template import loader
from django.utils.safestring import mark_safe
class MyWidget(Widget):
template_name = 'myapp/my_widget.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)
my_widget.html:
<textarea id="mywidget-{{ widget.name }}" name="{{ widget.name }}">
{% if widget.value %}{{ widget.value }}{% endif %}</textarea>
Run Code Online (Sandbox Code Playgroud)
现在使用表单呈现API呈现窗口小部件.
注意:这里有三个问题.对于前两个问题,请参阅AndiDog的更全面的答案.我这里只回答第三个问题:
问:什么样的窗口小部件方法负责从用户的输入回到数据模型?
A. value_from_datadict方法 - 它是小部件render方法的反转.这个方法可能就是小部件上的Django文档所说的"小部件处理HTML的呈现,以及从与小部件对应的GET/POST字典中提取数据".在文档中没有进一步的这一点,但你可以从内置小部件的代码中看到它是如何工作的.