在 Django 视图 class 中访问表单 'fields'

Access form 'fields' in django View class

我正在尝试访问基于 Class 的视图中的 'fields' 属性

这是我的 forms.py 的示例:

from django import forms
from .models import ErrorEvent


class ErrorEventForm(forms.ModelForm):

    class Meta:
        model = HumanErrorEvent
        # fields =
        exclude = ['event_id', 'user_modified', 'date_modified']
        widgets = {
            'owner': forms.TextInput(),
        }

那么这是我的观点:

class ErrorCreateView(CreateView):
    template_name = "forms/form.html"
    form_class = ErrorEventForm
    model = ErrorEvent

    def get_context_data(self, **kwargs):
        if not self.request.user.groups.filter(name='leaders').exists():
            self.form_class.fields['owner'].widget = forms.HiddenInput()
        context = super(ErrorCreateView, self).get_context_data(**kwargs)
        return context

我得到的错误是:

AttributeError: type object 'ErrorEventForm' has no attribute 'fields'

由于这一行:

self.form_class.fields['owner'].widget = forms.HiddenInput()

是否无法访问视图中的 'fields' 属性?如果没有,有没有办法根据用户所在的组隐藏 'owner' 表单域?

提前感谢您的帮助!

窗体的fields属性只是在窗体实例化时添加的,窗体class本身没有。此外,get_context_data 并不是执行此类操作的最佳方法,更好的方法可能是 get_form,因此您可以这样写:

def get_form(self, form_class=None):
    form = super().get_form(form_class=form_class)
    form.fields['owner'].widget = forms.HiddenInput()
    return form

但我们仍然可以做得更好!这样的逻辑不应该属于class本身的形式吗?因此,最好将用户简单地传递给表单 class。您可以通过覆盖 get_form_kwargs 和形式 __init__ 方法来做到这一点:

# Form
class ErrorEventForm(forms.ModelForm):

    class Meta:
        model = HumanErrorEvent
        # fields =
        exclude = ['event_id', 'user_modified', 'date_modified']
        widgets = {
            'owner': forms.TextInput(),
        }
    
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        if user and not user.groups.filter(name='leaders').exists():
            del self.fields['owner']  # Remove the field itself from the form
            self.instance.owner = user  # Set the user as the owner


# View
class ErrorCreateView(CreateView):
    template_name = "forms/form.html"
    form_class = ErrorEventForm
    model = ErrorEvent
    
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs