首页 > 解决方案 > Crispy Forms:FormHelper 用于拆分表单/两列相同模型

问题描述

我的模板分为两列。我只有一个模型,但旨在将表格分成两部分,一部分在第一列,另一部分在第二列。我的目标是将 FormHelper 用于 Crispy Forms。

可用文档给出了一个神秘的提示,但没有任何示例,这样的解释尝试有点短。

https://django-crispy-forms.readthedocs.io/en/d-0/tags.html#rendering-several-forms-with-helpers

使用助手渲染多个表单

我们经常被问到:“如何使用 {%crispy %} 标签渲染两个或多个表单,使用它们各自的助手,而不用两次渲染标签?” 简单,您需要在每个助手中将 form_tag 助手属性设置为 False:

self.helper.form_tag = False

然后你将不得不围绕表单编写一些 html 代码:

<form action="{% url submit_survey %}" class="uniForm" method="post">
    {% crispy first_form %}
    {% crispy second_form %}
</form>

更新:这篇文章解释了 Crispy 文档的 passus 为两个表单定义脆表单上下文名称合二为一

下面是我的代码。两个FormHelper将Model分成两部分,第一部分带字段:['car_model_make', 'status_is_secondhand'] 第二部分带字段:['seller', 'buyer']

我一直在寻找的是一种“调用”特定{% crispy form %}. 鉴于“帮助”文档”这样看起来{% crispy product-modelform_1 %}{% crispy product-modelform_2 %}哪些不起作用。

# models.py
class Product(models.Models):
    car_model_make = models.CharField(default='B', max_length=1, blank=True, choices=CAR_TYPE)
    status_is_secondhand = models.BooleanField(blank=True)
    seller = models.CharField(max_length=50, blank=True, choices=SELLER_TYPE)
    buyer = models.CharField(max_length=50, blank=True, choices=BUYER_TYPE)

# forms.py
class ProductForm(ModelForm):
    class Meta:
        model = Product
        fields = ('__all__')

    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-sm-4'
        self.helper.field_class = 'col-sm-8'
        self.helper.form_id = 'product-modelform'
        self.helper.form_tag = False


        model = 'car_model_make'
        secondhand = 'status_is_secondhand'

        self.fields[model].label = "Model"
        self.fields[secondhand].label = "Is Secondhand"

        self.helper.layout = Layout(
            Field(model),
            Field(secondhand),
            )

    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-sm-4'
        self.helper.field_class = 'col-sm-8'
        self.helper.form_id = 'product-modelform'
        self.helper.form_tag = False


        seller = 'seller'
        buyer = 'buyer'

        self.fields[seller].label = "Seller"
        self.fields[buyer].label = "buyer"

        self.helper.layout = Layout(
            Field(seller),
            Field(buyer),
            )

# views.py
class ProductFormView(FormView):
    form_class = ProductForm

    def form_valid(self, form):
        form.save()
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('index')

# urls.py
urlpatterns = [
    path('', index, name='index'),
    path('product/', ProductFormView.as_view(template_name='product/product.html'),


# html template

{% extends "product/base.html" %}
{% load crispy_forms_tags %}

{% block col8_content %}
<form id="product-modelform" method="post">
    {% csrf_token %}
    {% crispy form %}
    {% endblock col8_content %}
    {% block col4_content %}   
</form>
    {% endblock col4_content %}
    <input type="submit" value="Submit">

标签: pythondjangodjango-formsdjango-crispy-forms

解决方案


你不能有两种__init__方法,你实际上不需要它。您可以在<div>FormHelper() 的帮助下将这两个“列”包含在两个单独的标签中。

def __init__(self, *args, **kwargs):
      super(ProductForm, self).__init__(*args, **kwargs)
      self.helper = FormHelper()
      self.helper.form_class = 'form-horizontal'
      self.helper.label_class = 'col-sm-4'
      self.helper.field_class = 'col-sm-8'
      self.helper.form_id = 'product-modelform'
      self.helper.form_tag = False
      self.helper.layout = Layout(
      Div(
        Div('car_model_make','status_is_secondhand', css_class='col-lg-6 col-md-6 col-sm-12'),
        Div('seller','buyer', css_class='col-lg-6 col-md-6 col-sm-12'),
        css_class='row'
        )
      )

希望,这给了你诀窍。有关更多信息,请参阅布局


推荐阅读