2

基本思想是能够基于模型权限检查(使用基于类的通用视图)隐藏一些表单字段。很明显,我可以覆盖视图getpost检查表单权限并构造表单,但是没有更简洁的方法来实现这一点吗?

到目前为止,视图和形式都非常简单

class UserProfileUpdateView(UpdateView):
    model = UserProfile
    template_name = "profile/update.html"
    form_class = UserProfileForm


class UserProfileForm(forms.ModelForm):
def __init__(self, can_change_position=False, can_change_manager=False, *args, **kwargs):
    super(UserProfileForm, self).__init__(*args, **kwargs)
    self._process_permission('position', can_change_position)
    self._process_permission('manager', can_change_manager)

def _process_permission(self, field, permitted):
    if permitted:
        self.fields.append(field)

class Meta:
    model = UserProfile
    fields = ['field1', 'field2', 'field3', ...]

我是否遗漏了一些明显的东西,或者只是按照错误的方式?

更新看起来我的意图并不明确。我发布的代码中有一个错误,所以到目前为止给出的答案是如何修复错误。我已经修复了它,但问题不在于如何在运行时在表单上添加/删除字段(很明显)。问题是,是否有任何方法可以使用基于类的通用视图基于request值(例如)添加/删除字段。request.user

因此,再一次,直接的方法是重载getpost在视图上执行检查并实例化表单。但它在某种程度上重复了现有的 django 行为(即管理​​视图传递requestget_form)。那么,没有更清洁的方法来实现它吗?

4

2 回答 2

0

是的,您的__init__方法是在__new__方法之后调用的,该方法实际上使用了“Meta.exclude”属性。(当这种动态类魔术的声明性属性发生时)

看看django 源代码第 198 行。所以在运行时你已经拥有了所有的实例变量。

类似问题的解决方案,我在这里发布:

上传前未设置格式的 CSV 上传

希望有帮助

于 2013-04-16T00:39:58.273 回答
0

命名的属性base_fields是在表单类本身上设置的,在您的情况下是UserProfileForm. 当您创建此表单的实例时,即在表单实例上设置UserProfileForm()一个名为的属性,该属性是表单类上可用fields的副本。base_fields

并且base_fields设置在元类中,通常您不想更改元类。此外,Meta.exclude并且Meta.fields在元类中使用__new__,因此以形式更改它们__init__不会有任何效果。

因此,您可以做的是fields__init__.

代码:

class UserProfileForm(forms.ModelForm):
    def __init__(self, can_change_position=False, can_change_manager=False, *args, **kwargs):
        super(UserProfileForm, self).__init__(*args, **kwargs)
        self._process_permission('position', can_change_position)
        self._process_permission('manager', can_change_manager)         

    def _process_permission(self, field, permitted):
        if not permitted and field in self.fields:
            del self.fields[field]
于 2013-04-16T07:35:44.723 回答