基本思想是能够基于模型权限检查(使用基于类的通用视图)隐藏某些表单字段。 显然,我可以重写view的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行为(即,管理员视图将request传递给get_form )。 那么,难道没有更清洁的方法来实现这一目标吗?

===============>>#1 票数:0

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

看一下django源代码行198。因此在运行时,您已经具有所有实例变量。

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

CSV上载前未设置任何格式

希望能有所帮助

===============>>#2 票数:0

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

并且base_fields是在元类中设置的,通常您不希望更改元类。 此外, Meta.excludeMeta.fields在元类使用__new__ ,所以改变它们在__init__形式不会有任何影响。

因此,您可以做的是从__init__的表单实例的属性fields中删除不需要的fields

码:

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]

  ask by J0HN translate from so

未解决问题?本站智能推荐: