具有只读属性的Django Model表单

时间:2016-05-31 18:48:33

标签: python django forms

首先让我解释一下这个场景:我正在使用Django 1.8.7,Python 2.7和bootstrap作为前端的CRUD工作。在用户按下“添加”按钮的此CRUD列表中,将打开一个模式,其中包含一个组合,供用户选择他想要创建的项目类型。用户选择该选项,动态加载下一个表单。到目前为止它工作得很好。我的问题是:用户在列表中选择的组合是此表单的一个字段,并且此字段无法更改。它必须与文本一样。

示例:

目前的表格:

Current form

当网址为:domain.com/adm/products/add?category_id=2

时,表单应该是什么

enter image description here

当在查询字符串上传递category_id时,我不想让用户编辑这个值。

我的问题是:我怎样才能做到这一点?我正在使用CreateView作为视图,使用ModelForm作为表单。

提前感谢任何提示

2 个答案:

答案 0 :(得分:0)

只需在meta之前再次定义该字段。

class MyForm(ModelForm):
    inp_type = forms.CharField(widget = forms.TextInput(attrs={'readonly':'readonly'}))
    class meta:
        model = MyModel
        exclude = ['id']

答案 1 :(得分:0)

我找到了方法。首先,您必须创建一个自定义窗口小部件,以呈现您想要的方式。在我的情况下,原始小部件是一个组合(选择),所以我找到了这个小部件:

class ReadOnlySelect(Select):
    def render(self, name, value, attrs=None, choices=()):
        final_attrs = self.build_attrs(attrs, name=name)
        display = "None"
        for option_value, option_label in chain(self.choices, choices):
            if utf8_encode(option_value) == utf8_encode(value):
                display = option_label
        output = format_html('<p>%s</p><input type="hidden" value="%s"  %s> ' % (display, value, flatatt(final_attrs)))
        return mark_safe(output)

第二步,你必须设置字段的默认值,在CreateView中覆盖get_initial方法:

def get_initial(self):        
    category = None        
    if self.request.method == "GET" :
        # this method sets the initial value for the fields               
        try:
            category = Category.objects.get(pk=self.request.GET.get('category_id'))
        except Category.DoesNotExist:
            raise Http404(_(u"Destination not found."))

    return {'category': category}

设置要在字段中使用的窗口小部件的第三步:

class ItemForm(forms.ModelForm):
    class Meta:
        model = Item
        fields = ['category','title' ]
        widgets = {
            'category': ReadOnlySelect(),
        }

然后当django加载表单时,字段将显示为文本,后跟隐藏的输入。