I want to do something simple while using Crispy Forms; I want show a Fieldset only if the user belongs to the staff group. This is easily solved in a standard templates like th
You can pass the request context to your form from the view, and then use this in your form helper. Something like this:
In the view function that creates the form:
form = MyForm(request.POST, user=getattr(request, 'user', None))
Then in your form's __init__
method:
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(MyForm, self).__init__(args, kwargs)
And finally in your form layout code:
if user and user.is_staff:
self.helper.layout.append(Fieldset(
'Conditional Fieldset',
'field1',
'field2',
),
I've just appended this fieldset to the end of the layout. The documentation gives you other options for updating layouts on the fly.
I didn't find a cleaner way, so I completed it the way I had started.
Here's the view...
class ModelCreateView(LoginRequiredMixin, CreateView):
....
def get_form_kwargs(self):
# I am going to stuff the user object into the view so that
# I can use it in ModelForm to check the user and build the form
# conditionally
kwargs = super(ModelCreateView, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
In the ModelForm it was easiest to assume that the fields were always needed -- so I declared them all in the meta section -- then conditionally delete the fields, and conditionally append the form...
class YourCrispyForm(forms.ModelForm):
....
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(YourCrispyForm, self).__init__(*args, **kwargs)
# remove conditional fields
if self.user and self.user.is_staff:
pass
else:
del self.fields['field_name']
del self.fields['field_name']
del self.fields['field_name']
if self.user and self.user.is_staff:
self.helper.layout.append(
Fieldset(
'Conditional Sections',
Row(
Div('field_name', css_class="col-md-2"),
Div('field_name', css_class="col-md-2"),
...
),
)
)
It took me awhile to realizing that the deletion was the way to go. Hope that helps someone down the line.