Django创建一个只使用小部件读取的表单字段

ran*_*its 15 python forms django widget

我的表单字段如下所示:

class FooForm(ModelForm):
    somefield = models.CharField(
        widget=forms.TextInput(attrs={'readonly':'readonly'})
    )

    class Meta:
        model = Foo
Run Code Online (Sandbox Code Playgroud)

使用上面的代码得到如下错误:init()得到一个意外的关键字参数'widget'

我认为这是表单小部件的合法使用?

goo*_*orp 40

您应该使用表单字段而不是模型字段:

somefield = models.CharField(
    widget=forms.TextInput(attrs={'readonly':'readonly'})
)
Run Code Online (Sandbox Code Playgroud)

换成了

somefield = forms.CharField(
    widget=forms.TextInput(attrs={'readonly':'readonly'})
)
Run Code Online (Sandbox Code Playgroud)

应该解决它.


Ben*_*end 17

请注意,该readonly属性不会阻止Django处理客户端发送的任何值.如果对您来说重要的是价值不会改变,无论您的用户使用FireBug有多么富有创意,您都需要使用更复杂的方法,例如Alex Gaynor 在博客文章中演示的ReadOnlyField/ .ReadOnlyWidget


Mic*_*ael 5

我遇到了同样的问题,所以我创建了一个似乎适合我的用例的 Mixin。

class ReadOnlyFieldsMixin(object):
    readonly_fields =()

    def __init__(self, *args, **kwargs):
        super(ReadOnlyFieldsMixin, self).__init__(*args, **kwargs)
        for field in (field for name, field in self.fields.iteritems() if name in self.readonly_fields):
            field.widget.attrs['disabled'] = 'true'
            field.required = False

    def clean(self):
        cleaned_data = super(ReadOnlyFieldsMixin,self).clean()
        for field in self.readonly_fields:
           cleaned_data[field] = getattr(self.instance, field)

        return cleaned_data
Run Code Online (Sandbox Code Playgroud)

用法,只需定义哪些必须是只读的:

class MyFormWithReadOnlyFields(ReadOnlyFieldsMixin, MyForm):
    readonly_fields = ('field1', 'field2', 'fieldx')
Run Code Online (Sandbox Code Playgroud)