【问题标题】:Django Custom widget renderingDjango 自定义小部件渲染
【发布时间】:2019-02-27 16:01:17
【问题描述】:

一般问题

假设你有一个特定的模型

class MyModel(models.Model):
    Name = models.CharField(max_length=64)

以及用于创作的随附表格

class CreateMyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['name']

在正常情况下,当表单在模板中呈现时我通常会遍历模板中的字段

{%for field in form%}
{{field}}
{%endfor%}

当需要自定义样式时,我通常不得不将<div>s 和<span>s 放在该循环中,并在Meta 子类中指定基本小部件及其attrs

浏览该主题的Django Documentation,我知道似乎我必须使用Media 子类才能使所有操作都发生在Metawidgets 属性中,但我只是我无法理解它。

具体问题

假设我有一个模板,其中TextInput 表单需要呈现as in this template

<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>

如何创建一个小部件,以便我可以通过以下方式获得相同的结果:

class CreateMyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['name']
        widgets={'name':MyWidget(addon="Name",placeholder="MyModel Name")}

我知道占位符是我可以放在 TextInputattrs 初始化中的东西,但插件(或父 div,在这种情况下)不是 或者至少据我所知不是 em>

我很抱歉问了一个很长的问题,我只是觉得我需要彻底解释这个问题,因为它已经困扰了我一段时间......

【问题讨论】:

  • in addon="Name", Name 应该在 span 内吧?
  • @VaibhavVishal 不,你可以找到渲染的表单here,我正在尝试在“输入组”部分中渲染字段
  • 你必须在 for 循环中手动创建 div 和 span,你可以使用 {{ field.label }} 将文本动态放入 span 中
  • @VaibhavVishal 这就是我迄今为止一直在做的事情,在企业应用程序中跟踪大量 HTML 会让人感到沮丧。我希望这里有人有更好的解决方案!
  • 有很多方法可以做你想做的事,但这需要入侵 django,它们只会让你的代码更加复杂。

标签: django django-forms django-widget


【解决方案1】:

我们可以像下面这样。

小部件

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)

widget_template.html

<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>

【讨论】:

  • 请注意,小部件的 HTML 必须有一个 name 属性,否则 Django 管理员将无法读取它们的值,它们将被默默地排除在表单提交之外。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
  • 2012-08-06
  • 2012-08-24
  • 1970-01-01
相关资源
最近更新 更多