Reputation: 499
I am trying to access the 'fields' attribute in my Class based View
Here's an example of what my forms.py looks like:
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(),
}
Then here's my views:
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
The error I am getting is:
AttributeError: type object 'ErrorEventForm' has no attribute 'fields'
Due to this line:
self.form_class.fields['owner'].widget = forms.HiddenInput()
Is it not possible to access the 'fields' attribute in the views? If not, is there a way to hide the 'owner' form field based on the group the user is in?
Thank you for all your help in advance!
Upvotes: 1
Views: 1147
Reputation: 21787
The fields
attribute of the form is only added when the form is instantiated the form class itself does not have it. Also get_context_data
is not the best method to override for doing such things, a better method would perhaps be get_form
, so you could write something like:
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
form.fields['owner'].widget = forms.HiddenInput()
return form
But we can still do better than this! Shouldn't such logic belong to the form class itself? Hence it would be better to simply pass the user to the form class. You can do this by overriding get_form_kwargs
and the forms __init__
method:
# 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
Upvotes: 1