使用 Django 模型表单 + 表单向导 + Crispy - 不进行第二步
Posted
技术标签:
【中文标题】使用 Django 模型表单 + 表单向导 + Crispy - 不进行第二步【英文标题】:Using Django model forms + form wizard + Crispy - Does not proceed to second step 【发布时间】:2014-12-31 22:52:26 【问题描述】:我对 django 中的表单相当陌生。
我的问题是我有一些非常大的模型,我必须将它们分解成一系列较小的表格供用户填写。
所以我一直在玩脆表单,昨天在 youtube 上观看 Mike Hibberts 教程(Python Django 教程 19 - 使用表单向导)后,我想看看我是否可以使用脆表单来完成这项工作。
对我来说一切似乎都正常,但是当我按下提交时,表单似乎已经过验证,但没有继续执行第 2 步。
我这样做完全错了吗??
感谢您的任何帮助或建议!
forms.py
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, ButtonHolder
from crispy_forms.bootstrap import StrictButton
from models import ProcessSheet
class EnterData(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(EnterData, self).__init__(*args, **kwargs)
# If you pass FormHelper constructor a form instance
# It builds a default layout with all its fields
self.helper = FormHelper(self)
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'text-center col-lg-4'
self.helper.field_class = 'col-lg-8'
self.helper.layout.append(Submit('save', 'save'))
"""
self.helper.layout = Layout(
'sheet_id',
'sheet_title',
'part_name',
ButtonHolder('save', css_class='btn-warning'),
)
# You can dynamically adjust your layout
"""
class Meta:
model = ProcessSheet
fields = "__all__"
class Sheet1(forms.ModelForm):
def __init__(self, *args, **kwargs):
print "sheet 1 init!!!!!!!!!!!!!!!"
super(Sheet1, self).__init__(*args, **kwargs)
# If you pass FormHelper constructor a form instance
# It builds a default layout with all its fields
self.helper = FormHelper(self)
self.helper.form_tag = False
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'text-center col-lg-4'
self.helper.field_class = 'col-lg-8'
self.helper.layout = Layout(
'sheet_id',
'sheet_title',
'part_name',
)
class Meta:
model = ProcessSheet
fields = "__all__"
class Sheet2(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Sheet2, self).__init__(*args, **kwargs)
# If you pass FormHelper constructor a form instance
# It builds a default layout with all its fields
self.helper = FormHelper(self)
self.helper.form_tag = False
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'text-center col-lg-4'
self.helper.field_class = 'col-lg-8'
self.helper.layout = Layout(
'cooling',
'nozzle',
'zone_5',
)
class Meta:
model = ProcessSheet
fields = "__all__"
views.py
from django.shortcuts import render_to_response, RequestContext
from process_forms.models import ProcessSheet
from django.contrib.formtools.wizard.views import SessionWizardView
import logging
logr = logging.getLogger(__name__)
from forms import EnterData
# Create your views here.
def SheetSelect(request):
logr.debug( "IM IN SELECT!!!!!!!!!!!!" )
print "IM IN SELECT!!!!!!!!!!!!"
form = EnterData(request.POST or None)
log_data_message = "Please Enter Some Data"
if form.is_valid():
data = form.cleaned_data
if not ProcessSheet.objects.filter(sheet_id=data['sheet_id']):
save_it = form.save(commit=False)
save_it.save()
form = EnterData()
log_data_message = "Data Entered Ok!"
else:
log_data_message = "Sheet ID already exists!"
sheets = ProcessSheet.objects.all()
return render_to_response('PS14.html',
locals(),
context_instance=RequestContext(request))
def SheetFocus(request, sheet_id=0):
sheet = ProcessSheet.objects.get(id=sheet_id)
return render_to_response('PS24.html',
locals(),
context_instance=RequestContext(request))
class SheetWizard(SessionWizardView ):
logr.debug( "IM IN WIZARD!!!!!!!!!!!!" )
template_name = "sheet_form.html"
def done(self, form_list, **kwargs):
logr.debug( "IM IN DONE!!!!!!!!!!!!" )
form_data = process_form_data(form_list)
return render_to_response('done.html', 'form_data': form_data)
def process_form_data(form_list):
form_data = [form.cleaned_data for form in form_list]
logr.debug( "DONE PROCESS FORM DATA!!!!!!!!!!!!" )
return form_data
urls.py
from django.conf.urls import patterns, include, url
from process_forms.forms import Sheet1, Sheet2
from process_forms.views import SheetWizard
urlpatterns = patterns('',
url(r'^all/', 'process_forms.views.SheetSelect'),
url(r'^get/(?P<sheet_id>\d+)/', 'process_forms.views.SheetFocus'),
url(r'^entry/', SheetWizard.as_view([Sheet1,Sheet2])),
)
models.py
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
# Create your models here.
class ProcessSheet(models.Model):
ejector_confirmation_on = models.BooleanField(default=True)
number_of_cavities = models.IntegerField(blank=True, null=True,validators=[
MaxValueValidator(100),
MinValueValidator(1)
])
date = models.IntegerField(blank=True, null=True)
shift = models.IntegerField(blank=True, null=True,validators=[
MaxValueValidator(4),
MinValueValidator(1)
])
sheet_desc = models.TextField(blank=True, null=True)
comment = models.TextField(blank=True, null=True)
sheet_id = models.CharField(max_length=16, blank=False,null=True)
sheet_title = models.CharField(max_length=24, blank=False,null=True)
part_number = models.CharField(max_length=16, blank=False,null=True)
part_name = models.CharField(max_length=16, blank=True, null=True)
machine_no = models.CharField(max_length=16, blank=True, null=True)
special_notes = models.CharField(max_length=256,blank=True, null=True)
end_of_arm_tool_number = models.CharField(max_length=16, blank=True, null=True)
program_picker_robot = models.CharField(max_length=16, blank=True, null=True)
nozzle_tip_size = models.CharField(max_length=16, blank=True, null=True)
k_cut = models.BooleanField(default=False)
hydraulic_unit_pressure = models.CharField(max_length=16, blank=True, null=True)
valve_gate = models.CharField(max_length=16, blank=True, null=True)
colorant = models.CharField(max_length=16, blank=True, null=True)
reasons_for_changes = models.CharField(max_length=16, blank=True, null=True)
finger_print = models.CharField(max_length=16, blank=True, null=True)
initial = models.CharField(max_length=16, blank=True, null=True)
V1 = models.FloatField(blank=True, null=True)
V2 = models.FloatField(blank=True, null=True)
V3 = models.FloatField(blank=True, null=True)
V4 = models.FloatField(blank=True, null=True)
V5 = models.FloatField(blank=True, null=True)
position_pressure = models.FloatField(blank=True, null=True)
pack_1 = models.FloatField(blank=True, null=True)
pack_2 = models.FloatField(blank=True, null=True)
pack1 = models.FloatField(blank=True, null=True)
pack2 = models.FloatField(blank=True, null=True)
shot_size = models.FloatField(blank=True, null=True)
back_1 = models.FloatField(blank=True, null=True)
screw_speed = models.FloatField(blank=True, null=True)
cushion_in_inches = models.FloatField(blank=True, null=True)
injection_time = models.FloatField(blank=True, null=True)
cycle_time = models.FloatField(blank=True, null=True)
cooling = models.FloatField(blank=True, null=True)
hot_sprue_1 = models.FloatField(blank=True, null=True)
nozzle = models.FloatField(blank=True, null=True)
zone_1_barrel = models.FloatField(blank=True, null=True)
zone_2_barrel = models.FloatField(blank=True, null=True)
zone_3_barrel = models.FloatField(blank=True, null=True)
mold = models.FloatField(blank=True, null=True)
dryer = models.FloatField(blank=True, null=True)
zone_1 = models.FloatField(blank=True, null=True)
zone_2 = models.FloatField(blank=True, null=True)
zone_3 = models.FloatField(blank=True, null=True)
zone_4 = models.FloatField(blank=True, null=True)
zone_5 = models.FloatField(blank=True, null=True)
zone_6 = models.FloatField(blank=True, null=True)
zone_7 = models.FloatField(blank=True, null=True)
zone_8 = models.FloatField(blank=True, null=True)
zone_9 = models.FloatField(blank=True, null=True)
zone_10 = models.FloatField(blank=True, null=True)
zone_11 = models.FloatField(blank=True, null=True)
zone_12 = models.FloatField(blank=True, null=True)
flowmeter_reading = models.FloatField(blank=True, null=True)
def Meta():
managed = True
sheet_form.html
% extends "base.html" %
% block content %
<H1> This is the entry form </H1>
<p>Step wizard.steps.step1 of wizard.steps.count </p>
<br>
log_data_message
<form action="/sheets/entry/" method="post">
wizard.management_form
% load crispy_forms_tags %
% crispy wizard.form %
% if wizard.steps.prev %
<button name="wizard_goto_step" type="submit" value=" wizard.steps.first ">"first step"</button>
<button name="wizard_goto_step" type="submit" value=" wizard.steps.prev ">"prev step"</button>
% endif %
<input type="submit" value="Submit" />
</form>
% endblock %
% block links %
% for sheet in sheets %
<a HREF="/sheets/get/ sheet.id ">sheet.sheet_title</a>
<br>
% endfor %
% endblock %
<br>
祝你有美好的一天!!!
【问题讨论】:
【参考方案1】:对于未来的任何人,我认为我已经解决了我的问题。 我花了一点时间才弄清楚,但我坚持不懈的修补得到了回报。 抱歉,我没有详细说明我必须更改的内容,但我相信你们中的大多数人都可以从我发布的代码中看到更改。表格看起来很棒!会话向导按预期工作!一切似乎都很好。祝大家好运!!
forms.py 中的类
class Sheet1(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Sheet1, self).__init__(*args, **kwargs)
self.fields['machine_no'] = forms.ChoiceField(choices=get_site_choices())
self.helper = FormHelper(self)
self.helper.form_tag = False
#self.helper.label_class = 'text-center col-lg-4'
#self.helper.field_class = 'col-lg-8'
self.helper.layout = Layout(
HTML("% include \"progress_bar_min.html\" with value=\"1\" %"),
HTML("% include \"form_head_information.html\" with value=\""+str(args)+"\" %"),
TabHolder(
Tab(
'Sheet Information',
PrependedText('sheet_id', 'Django-'),
Alert(content='<strong>Automatically Generated ID!</strong> Just so you know.', css_class="alert-warning alert-dismissible"),
'sheet_title',
'part_name',
),
Tab(
'Press Location',
'machine_no',
'sheet_desc',
),
Tab(
'Comments',
Alert(content='<strong>Help Us Improve!</strong> Please leave lots of comments.', css_class="alert-info alert-dismissible"),
'comment',
),
),
ButtonHolder(
Submit('Save', 'Save', css_class='btn-info'),
Submit('wizard_goto_step', '0'),
Submit('wizard_goto_step', '1'),
Submit('wizard_goto_step', '2'),
),
)
query = ProcessSheet.objects.latest('id').sheet_id
self.fields['sheet_id'].widget.attrs['readonly'] = True
self.fields['sheet_id'].initial = query+'-'+str(time.time())
self.fields['sheet_id'].label = "ID For This Sheet"
self.fields['sheet_title'].label = "Enter A Title For This Sheet"
self.fields['part_name'].label = "Enter The Part Number"
class Meta:
model = ProcessSheet
fields =(
'sheet_id',
'sheet_title',
'part_name',
'machine_no',
'comment',
'sheet_desc',
)
sheet_form.html
% extends "base.html" %
% block content %
<H1> This is the entry form views_context_var</H1>
<p>Step wizard.steps.step1 of wizard.steps.count </p>
<br>
<form action="/sheets/entry/" method="post">
wizard.management_form
% load crispy_forms_tags %
% crispy wizard.form %
</form>
% endblock %
<br>
【讨论】:
还没有完全完成完整的实现,但我以此为例。我将评论我在答案中找到的内容。谢谢你写这篇文章。 您是否对 Sheet 2 进行了任何更改,还是仅使用 Sheet 1 作为示例? TestSheet1 和 TestSheet2 发生了什么?是因为你有你的 ModelForm 吗? 获取了您的代码,但按钮不是动态的,但您将它们设为静态。有原因吗? 你指的是页面导航按钮还是提交按钮? 页面导航。我让它的工作方式与你的类似,但现在我正要讨论如何让按钮显示“NEXT:”而不是脆形式的值。想法?【参考方案2】:我想我已经解决了一点问题,或者只是运气好。
在 forms.py 中 meta() 字段 = '__ all __'
需要更改以反映感兴趣的字段,我使用了变量 Sheet1_layout 和 Sheet2_layout。之后,向导似乎会继续下一步。
forms.py
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, ButtonHolder
from crispy_forms.bootstrap import StrictButton
from models import ProcessSheet
Sheet1_layout = (
'sheet_id',
'sheet_title',
'part_name',
)
class Sheet1(forms.ModelForm):
def __init__(self, *args, **kwargs):
print "sheet 1 init!!!!!!!!!!!!!!!"
super(Sheet1, self).__init__(*args, **kwargs)
# If you pass FormHelper constructor a form instance
# It builds a default layout with all its fields
self.helper = FormHelper(self)
self.helper.form_tag = False
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'text-center col-lg-4'
self.helper.field_class = 'col-lg-8'
self.helper.layout = Layout(Sheet1_layout,
ButtonHolder('save', css_class='btn-warning'),
)
self.helper.layout.append(Submit('save', 'Save'))
class Meta:
model = ProcessSheet
fields = Sheet1_layout
Sheet2_layout = (
'cooling',
'nozzle',
'zone_5',
)
class Sheet2(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Sheet2, self).__init__(*args, **kwargs)
# If you pass FormHelper constructor a form instance
# It builds a default layout with all its fields
self.helper = FormHelper(self)
self.helper.form_tag = False
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'text-center col-lg-4'
self.helper.field_class = 'col-lg-8'
self.helper.layout = Layout(Sheet2_layout,
ButtonHolder('finish', css_class='btn-warning'),
)
self.helper.layout.append(Submit('save', 'Finish'))
class Meta:
model = ProcessSheet
fields = Sheet2_layout
class TestSheet1(forms.Form):
sheet_id = forms.CharField(max_length=16)
class TestSheet2(forms.Form):
hello = forms.CharField(max_length=16)
【讨论】:
以上是关于使用 Django 模型表单 + 表单向导 + Crispy - 不进行第二步的主要内容,如果未能解决你的问题,请参考以下文章
在数据库中保存 Django 的表单向导 form_list 的最简单方法?