使用 1 个按钮 Django 提交 2 个自定义 Crispy 表单
我有 2 个表格,第二个表格引用第一个表格。我可以使用脆表单正确执行表单,但是,当我使用 helper = FormHelper() 自定义每个表单时,它们将不再一起提交。本质上,一个表单已提交,而另一个表单则认为它丢失了所有输入数据。
Forms.py
from django.forms import ModelForm, forms
from .models import Item, Item_dimensions
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Row, Column
# Create the form class.
class List_Item_Form(ModelForm):
class Meta:
model = Item
exclude = ('id','creator','created_on','updated_on' )
helper = FormHelper()
helper.layout = Layout(
Row(
Column('item_name', css_class='form-group col-md-6 mb-0'),
Column('price', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
),
'short_description',
'description',
Row(
Column('main_image', css_class='form-group col-md-2.5 mb-0'),
Column('image_2', css_class='form-group col-md-2.5 mb-0'),
Column('image_3', css_class='form-group col-md-2.5 mb-0'),
Column('image_4', css_class='form-group col-md-2.5 mb-0'),
Column('image_5', css_class='form-group col-md-2.5 mb-0'),
css_class='form-row'
),
'quantity'
)
helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))
helper.form_method = 'POST'
class List_Item_Dimensions(ModelForm):
class Meta:
model = Item_dimensions
exclude = ('id','item_id')
helper = FormHelper()
helper.layout = Layout(
Row(
Column('x_dim_mm', css_class='form-group col-md-4 mb-0'),
Column('y_dim_mm', css_class='form-group col-md-4 mb-0'),
Column('z_dim_mm', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
'weight_grams',
Submit('submit', 'add_listing')
)
helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))
helper.form_method = 'POST'
我尝试删除
helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))
并仅使用一个提交按钮,但它不起作用
Views.py
@login_required
def AddListing(request):
if request.method == 'POST':
form = List_Item_Form(request.POST,request.FILES)
dim_form = List_Item_Dimensions(request.POST)
if form.is_valid() and dim_form.is_valid():
itemName = form.cleaned_data['item_name']
price = form.cleaned_data['price']
s_desc = form.cleaned_data['short_description']
desc = form.cleaned_data['description']
quantity = form.cleaned_data['quantity']
main_img = form.cleaned_data['main_image']
image_2 = form.cleaned_data['image_2']
image_3 = form.cleaned_data['image_3']
image_4 = form.cleaned_data['image_4']
image_5 = form.cleaned_data['image_5']
x_dim = dim_form.cleaned_data['x_dim_mm']
y_dim = dim_form.cleaned_data['y_dim_mm']
z_dim = dim_form.cleaned_data['z_dim_mm']
weight = dim_form.cleaned_data['weight_grams']
current_user = request.user
model_instance = Item(creator=current_user, item_name=itemName,
price=price,short_description=s_desc,
description=desc, quantity=quantity,
main_image=main_img, image_2=image_2,
image_3=image_3, image_4 = image_4,
image_5=image_5)
dim_instance = Item_dimensions(x_dim_mm = x_dim,
y_dim_mm =y_dim,
z_dim_mm =z_dim,
weight_grams = weight)
model_instance.save()
# dim_instance.save(commit=False)
dim_instance.item_id = model_instance
dim_instance.save()
return HttpResponseRedirect('/user_profile/items/')
else:
form = List_Item_Form()
dim_form = List_Item_Dimensions()
return render(request, 'store/add_listing.html', {'form': form,'dim_form':dim_form})
template.html
{% block content %}
<div>
<h1> list a new item </h1>
{% load crispy_forms_tags %}
{% csrf_token %}
<form method="post", enctype="multipart/form-data">{% csrf_token %}
{% crispy form %}
{% crispy dim_form %}
{% comment %} {{ form|crispy }}
{{ dim_form|crispy }} {% endcomment %}
<input name="submit" type="post" value="template button">
</form>
</div>
{% endblock content %}
I have 2 forms with the second form referencing the first form. I can get the forms to execute correctly using crispy forms, however, when I customize each form using helper = FormHelper() they will no longer submit together. Essentially one form is submitted and the other form thinks it is missing all of its input data.
Forms.py
from django.forms import ModelForm, forms
from .models import Item, Item_dimensions
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Row, Column
# Create the form class.
class List_Item_Form(ModelForm):
class Meta:
model = Item
exclude = ('id','creator','created_on','updated_on' )
helper = FormHelper()
helper.layout = Layout(
Row(
Column('item_name', css_class='form-group col-md-6 mb-0'),
Column('price', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
),
'short_description',
'description',
Row(
Column('main_image', css_class='form-group col-md-2.5 mb-0'),
Column('image_2', css_class='form-group col-md-2.5 mb-0'),
Column('image_3', css_class='form-group col-md-2.5 mb-0'),
Column('image_4', css_class='form-group col-md-2.5 mb-0'),
Column('image_5', css_class='form-group col-md-2.5 mb-0'),
css_class='form-row'
),
'quantity'
)
helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))
helper.form_method = 'POST'
class List_Item_Dimensions(ModelForm):
class Meta:
model = Item_dimensions
exclude = ('id','item_id')
helper = FormHelper()
helper.layout = Layout(
Row(
Column('x_dim_mm', css_class='form-group col-md-4 mb-0'),
Column('y_dim_mm', css_class='form-group col-md-4 mb-0'),
Column('z_dim_mm', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
'weight_grams',
Submit('submit', 'add_listing')
)
helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))
helper.form_method = 'POST'
I have tried removing
helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))
and using just one submit button but it didn't work
Views.py
@login_required
def AddListing(request):
if request.method == 'POST':
form = List_Item_Form(request.POST,request.FILES)
dim_form = List_Item_Dimensions(request.POST)
if form.is_valid() and dim_form.is_valid():
itemName = form.cleaned_data['item_name']
price = form.cleaned_data['price']
s_desc = form.cleaned_data['short_description']
desc = form.cleaned_data['description']
quantity = form.cleaned_data['quantity']
main_img = form.cleaned_data['main_image']
image_2 = form.cleaned_data['image_2']
image_3 = form.cleaned_data['image_3']
image_4 = form.cleaned_data['image_4']
image_5 = form.cleaned_data['image_5']
x_dim = dim_form.cleaned_data['x_dim_mm']
y_dim = dim_form.cleaned_data['y_dim_mm']
z_dim = dim_form.cleaned_data['z_dim_mm']
weight = dim_form.cleaned_data['weight_grams']
current_user = request.user
model_instance = Item(creator=current_user, item_name=itemName,
price=price,short_description=s_desc,
description=desc, quantity=quantity,
main_image=main_img, image_2=image_2,
image_3=image_3, image_4 = image_4,
image_5=image_5)
dim_instance = Item_dimensions(x_dim_mm = x_dim,
y_dim_mm =y_dim,
z_dim_mm =z_dim,
weight_grams = weight)
model_instance.save()
# dim_instance.save(commit=False)
dim_instance.item_id = model_instance
dim_instance.save()
return HttpResponseRedirect('/user_profile/items/')
else:
form = List_Item_Form()
dim_form = List_Item_Dimensions()
return render(request, 'store/add_listing.html', {'form': form,'dim_form':dim_form})
template.html
{% block content %}
<div>
<h1> list a new item </h1>
{% load crispy_forms_tags %}
{% csrf_token %}
<form method="post", enctype="multipart/form-data">{% csrf_token %}
{% crispy form %}
{% crispy dim_form %}
{% comment %} {{ form|crispy }}
{{ dim_form|crispy }} {% endcomment %}
<input name="submit" type="post" value="template button">
</form>
</div>
{% endblock content %}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
{% Crispy form %}
会自动添加标签,除非您另外指定
form_tag = False
。请参阅 https://django-crispy-forms.readthedocs.io/en /latest/form_helper.html这里您已经给出了一个外部标签,因此其中的
crispy
标签将创建嵌套表单。这会使您的 HTML 无效。检查 https://django-crispy-forms .readthedocs.io/en/latest/crispy_tag_forms.html#crispy-tag-formsPS:(还没用过最近的 django) - 您不需要在构造函数中包含帮助程序和其他自定义吗?
{% crispy form %}
automatically adds<form></form>
tags unless otherwise you specifyform_tag = False
. See https://django-crispy-forms.readthedocs.io/en/latest/form_helper.htmlHere you've already given an outer tag and hence the
crispy
tags inside it will create nested forms. This makes your HTML invalid. Check https://django-crispy-forms.readthedocs.io/en/latest/crispy_tag_forms.html#crispy-tag-formsPS: (Haven't used django recently) - don't you need to include the helper and other customisations inside the constructor?
扩展@art的答案,这就是您可能想要的:
并且您可以以相同的方式将它们渲染在模板内:
另请注意,添加 {% csrf_token %} 只是添加一个额外的隐藏表单字段,类似于以下内容
: csrf 令牌没有坏处,但也没有必要。
虽然与原来的问题并不严格相关,但我也想提出一些建议。在处理 ModelForms 时,Django 在幕后做了很多魔法。这意味着您可以省去手动获取视图中所有模型字段以创建新模型实例的麻烦。我还没有对此进行测试,但您的视图很可能会大大简化为类似的内容:
Expanding on @art's answer, here's what you probably want:
And you'd render them inside of your template in the same way:
Also note that adding {% csrf_token %} simply adds an additional hidden form field similar to the following:
Adding additional csrf tokens doesn't hurt, but also isn't necessary.
While not strictly related to the original question, I'd also like to give a word of advice. When dealing with ModelForms, Django does lots of magic behind the scenes. What this means is that you can save yourself the headache of manually grabbing all of your model's fields in your view to create a new model instance. I haven't tested this, but your view could most likely be greatly simplified to something similar this :