在Django'中禁用表单字段;s CreateView

在Django'中禁用表单字段;s CreateView,django,django-forms,django-class-based-views,django-generic-views,Django,Django Forms,Django Class Based Views,Django Generic Views,这个问题也可以表述为:“如何更改CreateView生成表单的属性?” 我使用“CreateView”在Django 1.10中生成一个视图和相关表单。其思想是,普通用户(教师)只能以自己的身份创建模型的实例,但特权用户可以创建实例并分配给任何教师。我想对两者使用相同的视图/表单 模型: class Set(models.Model): name = models.CharField( max_length=40, ) matter = models.Fo

这个问题也可以表述为:“如何更改CreateView生成表单的属性?”

我使用“CreateView”在Django 1.10中生成一个视图和相关表单。其思想是,普通用户(教师)只能以自己的身份创建模型的实例,但特权用户可以创建实例并分配给任何教师。我想对两者使用相同的视图/表单

模型:

class Set(models.Model):
    name = models.CharField(
        max_length=40,
    )
    matter = models.ForeignKey(
        Matter,
        on_delete=models.SET_NULL,
        null=True,
    )
    group = models.ForeignKey(
        Group,
        on_delete=models.SET_NULL,
        null=True,
    )
    teacher = models.ForeignKey(
        Teacher,
        on_delete=models.PROTECT,
    )
从技术上讲,它将包括使用当前登录的“教师”填充表单,并禁用该字段,除非当前用户具有特权。我目前使用以下代码进行初始值设置,但我不知道如何防止普通用户修改“教师”字段

我尝试的另一个选项是使用正确的“教师”创建实例,如:

class SetCreate(LoginRequiredMixin, CreateView):
    model = Set
    fields = ('name', 'matter', 'group')

    def form_valid(self, form):
        form.instance.teacher = self.request.user.teacher
        return super(SetCreate, self).form_valid(form)
它工作得很好,但是我不能用它来编辑特权用户的“教师”字段

我知道表单字段中存在“Field.disable”属性,但如果可能,我不知道如何更改“CreateView”生成表单的属性

另一个选择是限制表单中下拉列表中的选项,但我也不知道如何做


欢迎提供包含不同观点的任何建议。

查看代码,编辑视图会根据
字段
属性的值在
get\u form\u类
中生成一个表单。它被定义为类属性,但代码实际上通过
self.fields
引用它,因此没有理由不能在实例级别重写它。所以,你可以这样做:

class SetCreate(LoginRequiredMixin, CreateView):
    model = Set
    fields = ('name', 'matter', 'group')

    def get_form_class(self, *args, **kwargs):
        if self.request.user.has_the_right_permission():
            self.fields += ('teacher',)
        else:
            self.fields = self.fields
        return super(SetCreate, self).get_form_kwargs(*args, **kwargs)

(看似毫无意义的else块是为了确保始终设置一个实例变量。)

看起来不错,但它只适用于编辑表单,而不是创建表单。在创建模式下,普通用户实际上会定义一个“教师”字段,但仅定义为他自己。理想情况下,只需在生成表单时在“教师”字段中设置“disabled”属性即可解决此问题,但我不知道要重写什么方法来完成此操作。您可以使用上面显示的
form\u valid
代码,再次在检查权限的if块中执行此操作。
class SetCreate(LoginRequiredMixin, CreateView):
    model = Set
    fields = ('name', 'matter', 'group')

    def get_form_class(self, *args, **kwargs):
        if self.request.user.has_the_right_permission():
            self.fields += ('teacher',)
        else:
            self.fields = self.fields
        return super(SetCreate, self).get_form_kwargs(*args, **kwargs)