有条件地显示带有脆弱形式的Fieldset

时间:2016-04-19 00:02:47

标签: python django django-forms django-crispy-forms

我想在使用Crispy Forms时做一些简单的事情;我想只在用户属于职员组时显示一个Fieldset。这可以在像这样的标准模板中轻松解决:

{% if user.is_staff %} show extra stuff {% endif %}

也许我错过了手册中的内容,但我不知道如何将“{%if user.is_staff%}”这样的模板标签注入到酥脆的布局中。如果我能使用虚构的'Djangotag'来解决我的问题,那么它将是我的用例的理想选择:

self.helper.layout = Layout(
   Fieldset(
       'Section One',
       'name',
       'description',
   ),
   Djangotag('{% if user.is_staff %}'),
   Fieldset(
       'Conditional Fieldset',
       'field1',
       'field2',
   ),
   Djangotag('{% endif %}'),      
   Fieldset(
       'More Details',
       'detail1',
       'detail2',
   ),
  )

有一种简单的方法可以用脆形式做到这一点吗?

注意:我已经实施了self.user = kwargs.pop('user')方法并且它不是很优雅,我仍然在寻找更好的东西。

我也尝试为if语句创建了简单模板,并尝试了这个HTML("{% include 'helpers/is_staff.html' %}"),,但渲染过程失败了。

3 个答案:

答案 0 :(得分:2)

您可以从视图中将请求上下文传递给表单,然后在表单助手中使用它。像这样:

在创建表单的视图函数中:

form = MyForm(request.POST, user=getattr(request, 'user', None))

然后在您的表单中__init__方法:

def __init__(self, *args, **kwargs):
    self.user = kwargs.pop('user', None)
    super(MyForm, self).__init__(args, kwargs)

最后在你的表单布局代码中:

if user and user.is_staff:
    self.helper.layout.append(Fieldset(
        'Conditional Fieldset',
        'field1',
        'field2',
    ),

我刚刚将此字段集附加到布局的末尾。 documentation为您提供了动态更新布局的其他选项。

答案 1 :(得分:0)

我没有找到更干净的方式,所以我按照我开始的方式完成了它。

这是观点...

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

在ModelForm中,最简单的假设是总是需要字段 - 所以我在meta部分中声明了它们 - 然后有条件地删除字段,并有条件地附加表单......

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"),
                ...
            ),
          )
        )

我花了一些时间才意识到删除是要走的路。希望能有所帮助。

答案 2 :(得分:0)

用 Python(TM) 做

脆皮表单的中心思想是在 Python 中做更多的事情,而在模板中做的更少。 因此,我的脆皮形式通常是这样称呼的

  {% crispy form form.get_formhelper %}

get_formhelper 函数中,我从头开始添加 Layout 对象,全部以编程方式,在需要动态适应的任何地方,如下所示:

import crispy_forms.helper as cfh
import crispy_forms.layout as cfl

def get_formhelper():
    helper = cfh.FormHelper()   
    layout = cfl.Layout()
    fieldset = cfl.Fieldset("Fieldset Title")
    fieldset.fields.append('myfield')
    ...
    layout.fields.append(fieldset)
    ...
    helper.layout = layout
    return helper

这提供了最大的灵活性,并使布局逻辑与其他表单逻辑很好地分开。