Conditionally display a Fieldset with Crispy Forms

前端 未结 2 1990
死守一世寂寞
死守一世寂寞 2021-01-27 11:57

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

相关标签:
2条回答
  • 2021-01-27 12:47

    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.

    0 讨论(0)
  • 2021-01-27 12:47

    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.

    0 讨论(0)
提交回复
热议问题