Python 有条件地显示具有清晰表单的字段集

Python 有条件地显示具有清晰表单的字段集,python,django,django-forms,django-crispy-forms,Python,Django,Django Forms,Django Crispy Forms,我想做一些简单的事,同时使用脆的形式;我只想在用户属于staff组时显示字段集。这在以下标准模板中很容易解决: {%if user.is_staff%} 展示额外的东西 {%endif%} 也许我遗漏了手册中的一些内容,但我不明白如何将类似“{%if user.is_staff%}”的模板标记注入到crispy表单布局中。如果我可以像下面这样使用虚构的“Djangotag”来解决我的问题,这将是我的用例的理想选择: self.helper.layout = Layout( Fields

我想做一些简单的事,同时使用脆的形式;我只想在用户属于staff组时显示字段集。这在以下标准模板中很容易解决:


{%if user.is_staff%}
展示额外的东西
{%endif%}

也许我遗漏了手册中的一些内容,但我不明白如何将类似“{%if user.is_staff%}”的模板标记注入到crispy表单布局中。如果我可以像下面这样使用虚构的“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%}”)
,但渲染过程失败

您可以将请求上下文从视图传递到表单,然后在表单帮助器中使用它。大概是这样的:

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

form = MyForm(request.POST, user=getattr(request, 'user', None))
然后在表单的
\uuuu init\uuuu
方法中:

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',
    ),

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

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

这里是风景

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"),
                ...
            ),
          )
        )
我花了一段时间才意识到删除是正确的选择。希望这能帮助其他人。

用Python(TM)实现 crispy表单的核心思想是在Python中做更多的事情,而在模板中做更少的事情。 因此,我的脆饼通常被这样称呼

  {% crispy form form.get_formhelper %}
get\u 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

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

这正是我开始实现的方法。然后我意识到我将不得不胡乱添加字段和小部件等。Django框架非常优雅地解决了这个用例,以至于这个黑客很快就变得丑陋起来,而且看起来我无法接受,即使它是有效的。