阿晨1998
您好,很高兴为您解答。12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394from django.utils.translation import ugettext_lazy as _ from django import forms from django.forms.formsets import BaseFormSet from django.forms.fields import FileField from django.forms.util import ValidationError from django.shortcuts import render_to_response from django.contrib.formtools.wizard import FormWizard from ddtcms.office.equipment.models import Equipment,Characteristic,CharacteristicValue class EquipmentForm(forms.ModelForm): class Meta: model = Equipment class CharacteristicValueForm(forms.Form): def clean(self): a=self.fields s=self.data self.cleaned_data = {} # 下面的这一段for 是从 django的forms.py中的 full_clean 中复制来的 for name, field in self.fields.items(): # value_from_datadict() gets the data from the data dictionaries. # Each widget type knows how to retrieve its own data, because some # widgets split data over several HTML fields. value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) try: if isinstance(field, FileField): initial = self.initial.get(name, field.initial) value = field.clean(value, initial) else: value = field.clean(value) self.cleaned_data[name] = value if hasattr(self, 'clean_%s' % name): value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value except ValidationError, e: self._errors[name] = self.error_class(e.messages) if name in self.cleaned_data: del self.cleaned_data[name] #cl=self.cleaned_data #debug()<<<调试用的,查看cl的值,主要是看self.cleaned_data的值,如果return了,就看不到了 return self.cleaned_data class EquipmentCreateWizard(FormWizard): def done(self, request, form_list): return render_to_response('equipment/done.html', { 'form_data': [form.cleaned_data for form in form_list], }) def get_form(self, step, data=None): "Helper method that returns the Form instance for the given step." form = self.form_list[step](data, prefix=self.prefix_for_step(step), initial=self.initial.get(step, None)) if step == 1: if data: cg = data.get('0-category', 1) cs = Characteristic.objects.all().filter(category__id=cg) for c in cs: form.fields['Characteristic-'+str(c.id)] = forms.CharField(label = c.name) g=form.fields #debug() return form # 从wizard.py中复制过来进行更改的. def render(self, form, request, step, context=None): "Renders the given Form object, returning an HttpResponse." old_data = request.POST prev_fields = [] if old_data: hidden = forms.HiddenInput() # Collect all data from previous steps and render it as HTML hidden fields. for i in range(step): old_form = self.get_form(i, old_data) hash_name = 'hash_%s' % i prev_fields.extend([bf.as_hidden() for bf in old_form]) prev_fields.append(hidden.render(hash_name, old_data.get(hash_name, self.security_hash(request, old_form)))) if step == 1: cg = old_data.get('0-category', 1) cs = Characteristic.objects.all().filter(category__id=cg) for c in cs: form.fields['Characteristic-'+str(c.id)] = forms.CharField(label = c.name) g=form.fields #debug() if step == 2: debug() return super(EquipmentCreateWizard, self).render(form, request, step, context=None) def get_template(self, step): return 'equipment/wizard_%s.html' % stepEquipmentCreateWizard其实也可以放在views.py中,而且我觉得更合理一点.在EquipmentCreateWizard 中,我试着修改过process_step 函数,但是得不到正确的结果,后来修改了get_form,都是想从django的formtools的wizard.py中复制过来再进行修改的.get_form的修改也没有得到正确的结果.后来就修改render函数,在第2步的时候,我将动态参数个数显示出来了.但是到最后结束done的环节,取得的formdata中,第二个form没有数据,就是一个空的{},于是我又重新修改get_form函数,无非就是判断是不是第二步,然后给第二个form动态添加几个field:1234567if step == 1: cg = old_data.get('0-category', 1) cs = Characteristic.objects.all().filter(category__id=cg) for c in cs: form.fields['Characteristic-'+str(c.id)] = forms.CharField(label = c.name) g=form.fields #debug()这段代码在get_form和 render中都有,都是判断是不是第2步,然后就根据第1步中选择的设备的分类来查询到具体的分类,再根据分类来获取该种分类的设备有哪些参数,然后根据参数个数修改form的参数field的个数.'Characteristic-'+str(c.id)是用来以后保存数据的时候,split这个字符串,得到参数的id,并在参数值表中保存Characteristic-1,Characteristic-2...的value.g=form.fields#debug()用来断点查看参数field有多少个,是否修改成功. =========================123456789from django.conf.urls.defaults import * from ddtcms.office.equipment.forms import EquipmentForm,CharacteristicValueForm,EquipmentCreateWizard urlpatterns = patterns('ddtcms.office.equipment.views', url(r'^$', 'index', name="equipment_index"), url(r'^add/$', 'equipment_create', name="equipment_create"), url(r'^add-by-wizard/$',EquipmentCreateWizard([EquipmentForm, CharacteristicValueForm]), name="equipment_create_by_wizard"), ) 以上代码,csdnbolg 自动过滤了 $符号,我加了上去,可能有不对的地方.==========================wizard_0.html12345678910111213141516{% block content %} <h2>添加/修改设备向导</h2> <p>第 {{ step }} 步, 共 {{ step_count }} 步.</p> <p>填写设备基本情况</p> <form method="POST" action="">{% csrf_token %} <table> {{ form }} </table> <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" /> {{ previous_fields|safe }} <input type="submit" value="Submit" /> </form> {% endblock %}===================wizard_1.html12345678910111213141516{% block content %} <h2>添加/修改设备向导</h2> <p>第 {{ step }} 步, 共 {{ step_count }} 步.</p> <p>填写设备参数, 如果没有要填写的内容, 请直接点击确定.</p> <form method="POST" action="">{% csrf_token %} <table> {{ form }} </table> <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" /> {{ previous_fields|safe }} <input type="submit" value="Submit" /> </form> {% endblock %}====================done.html12345678{% block content %} <h2>添加/修改设备向导</h2> <p>您已经成功添加了一个设备.</p> {{form_data}} {% endblock %}============还可以用另外的form来实现formwizard,就是第一个form1,主要用来让用户选择设备的分类,form2就根据前面的来动态生成参数的表单.原理是一样的.还有就是写2个view来模拟formwizard,第一个view增加一个设备,第二个view带设备id这个参数即可,可以很有效的增加设备的参数.