基于类的视图,将数据添加到表单

时间:2016-05-25 09:35:45

标签: django django-models django-forms

我试图实现我认为非常基本的东西,但似乎无法找到解决方案。

我正在创建一个非常通用的视图,用于在django应用中创建和更新用户。我有一个'提供商'具有相关权限的模型。我想以一种非常简单的方式添加权限管理。当我显示表单时,复选框应该检查用户是否有权添加/删除/修改,另一方面,当选中复选框时,应该在数据库中设置权限。

它是这样的:

class UserUpdate(UpdateView):
    form_class = UserForm
    model = User

    def get_initial(self):
        user = self.get_object()
        if user is not None and user.has_perm('core.add_provider'):
            return { 'right_provider' : True }

    def form_valid(self, form):
    user = form.save(commit=False)

    if form.right_provider:
        user.user_permissions.add('core.add_provider', 'core.change_provider', 'core.delete_provider')
    else:
        user.user_permissions.remove('core.add_provider', 'core.change_provider', 'core.delete_provider')
    return super().form_valid(form)

然后是表格:

class UserForm(ModelForm):

    right_provider = BooleanField(label='Right Provider', required=False)

    class Meta:
        model = User
        fields = ['username', 'email', 'first_name', 'last_name']

显然不是这样做的,因为' UserForm'对象没有属性' right_provider'

我做得对吗,如果是这样,这段代码有什么问题? 是否存在关于如何在ModelForm和模型之间来回传递数据的文章?

2 个答案:

答案 0 :(得分:2)

您可以从表单def form_valid(self, form): if form.cleaned_data['right_provider']: ... else: ... return super().form_valid(form) def form_valid(self, form): if form.cleaned_data['right_provider']: ... else: ... return super().form_valid(form) 获取值。

save()

注意我已移除super()来电 - 当您致电super()时,表单会自动保存。

如果您确实需要在视图中调用保存,我会避免拨打save_m2m。我认为它更清楚,它避免了def form_valid(self, form): user = form.save(commit=False) ... user.save() # save the user to the db form.save_m2m() # required if the form has m2m fields return HttpResponseRedirect(self.get_success_url()) 未被调用的潜在问题。有关save method表单的详细信息,请参阅文档。

super()

另一个选择是首先调用self.object而不返回,然后访问def form_valid(self, form): response = super().form_valid(form) user = self.object if form.cleaned_data['right_provider']: ... else: ... return response ,最后返回响应。

{{1}}

答案 1 :(得分:0)

模型表单期望表单字段与模型字段匹配。因此,您可以将其作为字段添加到模型中。

如果您只想要表单上的字段,则需要将其添加到表单的 innit 方法中。

class UserFrom(ModelForm)

    def __init__(self, **kwargs)
        super(UserForm, self).__init__(**kwargs)

        # probably some code here to work out the initial state of the checkbox, 
        self.fields['right_provider'] = forms.BooleanField(label='Right Provider', required=False)