【问题标题】:Read-only form in template, django模板中的只读表单,django
【发布时间】:2015-08-19 12:12:14
【问题描述】:

如何在模板上而不是在模型或视图中将输入设为只读?

例如在

{% for form in formset %}
            {{ form.id }}
            <tr>
                <th>{{ form.project_name }}</th>

如果可能的话,我需要通过 html 将{{ form.project_name }} 设为只读(仍为表单)(它在 model.py 中有默认值)

编辑。我需要它是只读的浏览器,而不是只读的表单。

【问题讨论】:

标签: django


【解决方案1】:

如果您想让所有字段在模板级别只读,请使用 HTML &lt;fieldset&gt; disabled 属性:

    <form action="{% url "app.views.fonction" %}" method="post">{% csrf_token %}
        <h2>{% trans "Any title" %}</h2>
        <fieldset disabled="disabled">
            {{ form.as_ul }}
        </fieldset>
    <input type="submit" class="any" value="any" />
    </form>

【讨论】:

    【解决方案2】:

    如果您想在 HTML 中创建 input 字段 readonly,您必须自己编写所有必需的 HTML。

    HTML

    <input type="text" value="{{ object.field_1 }}" readonly />
    <input type="text" value="{{ object.field_2 }}" readonly />
    
    <!-- And so on -->
    

    【讨论】:

      【解决方案3】:

      有一个很好的答案here

      您可以通过小部件的 attributes 属性将必要的 html 添加到表单字段:

      myform.fields['thefield'].widget.attrs['readonly'] = True
      

      这样你仍然可以在模板中书写

      {{myform.thefield.label_tag}}
      {{myform.thefield}}
      

      Django 会将readonly="True" 放入&lt;input ...&gt;

      【讨论】:

        【解决方案4】:

        最简洁的方法是创建一个具有只读字段meta 选项的新表单基类,并为您完成其余工作。

        您不应该在模板中包含任何逻辑,而是在视图中验证数据,并将 let django 呈现只读输入作为span widget

        我在生产中使用它并取得了巨大成功。

        class SpanWidget(forms.Widget):
            '''Renders a value wrapped in a <span> tag.
        
            Requires use of specific form support. (see ReadonlyForm
            or ReadonlyModelForm)
            '''
        
            def render(self, name, value, attrs=None):
                final_attrs = self.build_attrs(attrs, name=name)
                return mark_safe(u'<span%s >%s</span>' % (
                    forms.util.flatatt(final_attrs), self.display_value))
        
            def value_from_datadict(self, data, files, name):
                return self.original_value
        
        
        class SpanField(forms.Field):
            '''A field which renders a value wrapped in a <span> tag.
        
            Requires use of specific form support. (see ReadonlyForm
            or ReadonlyModelForm)
            '''
        
            def __init__(self, *args, **kwargs):
                kwargs['widget'] = kwargs.get('widget', SpanWidget)
                super(SpanField, self).__init__(*args, **kwargs)
        class Readonly(object):
            '''Base class for ReadonlyForm and ReadonlyModelForm which provides
            the meat of the features described in the docstings for those classes.
            '''
        
            class NewMeta:
                readonly = tuple()
        
            def __init__(self, *args, **kwargs):
                super(Readonly, self).__init__(*args, **kwargs)
                readonly = self.NewMeta.readonly
                if not readonly:
                    return
                for name, field in self.fields.items():
                    if name in readonly:
                        field.widget = SpanWidget()
                    elif not isinstance(field, SpanField):
                        continue
                    model_field = self.instance._meta.get_field_by_name(name)[0]
                    field.widget.original_value = model_field.value_from_object(self.instance)
                    field.widget.display_value = unicode(getattr(self.instance, name))
        
        
        class ReadonlyForm(Readonly, forms.Form):
            '''A form which provides the ability to specify certain fields as
            readonly, meaning that they will display their value as text wrapped
            with a <span> tag. The user is unable to edit them, and they are
            protected from POST data insertion attacks.
        
            The recommended usage is to place a NewMeta inner class on the
            form, with a readonly attribute which is a list or tuple of fields,
            similar to the fields and exclude attributes on the Meta inner class.
        
                class MyForm(ReadonlyForm):
                    foo = forms.TextField()
                    class NewMeta:
                        readonly = ('foo',)
            '''
            pass
        
        
        class ReadonlyModelForm(Readonly, forms.ModelForm):
            '''A ModelForm which provides the ability to specify certain fields as
            readonly, meaning that they will display their value as text wrapped
            with a <span> tag. The user is unable to edit them, and they are
            protected from POST data insertion attacks.
        
            The recommended usage is to place a NewMeta inner class on the
            form, with a readonly attribute which is a list or tuple of fields,
            similar to the fields and exclude attributes on the Meta inner class.
        
                class Foo(models.Model):
                    bar = models.CharField(max_length=24)
        
                class MyForm(ReadonlyModelForm):
                    class Meta:
                        model = Foo
                    class NewMeta:
                        readonly = ('bar',)
            '''
            pass
        

        这是我在production中使用的代码:

        class MembershipForm(ReadonlyModelForm):
            class Meta:
                model = Membership
                fields = ('user','board', 'privileged', 'alumni')
        
            class NewMeta:
                readonly = ('user')
            def email(self):
                return self.instance.user.email
        

        【讨论】:

          猜你喜欢
          • 2015-11-21
          • 2017-05-07
          • 1970-01-01
          • 2014-02-28
          • 2015-04-17
          • 1970-01-01
          • 2013-07-17
          • 2016-08-21
          • 2012-01-03
          相关资源
          最近更新 更多