2011-04-26 58 views
1

请帮我看看我的问题:) 我有三种模式:Django的多页表格

# Genre model 
class Genre(models.Model): 
    title = models.CharField(...) 

# Author model 
class Author(models.Model): 
    name = models.CharField(...) 
    genre = models.ForeignKey(Author) 

# Book model 
class Book(models.Model): 
    genre = models.ForeignKey(Genre) 
    title = models.CharField(...) 
    author = models.ForeignKey(Author) 

我想创建两步形式Book模型:
第1页 - 选择类型
第2页 - 标题和相关选择的类型作者

如何在没有ajax和javascript的情况下做到这一点?

+0

看看http://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/ - 我不知道如何编辑第二个窗体的上下文,但它可能会成为可能。 – 2011-04-26 19:27:05

+0

谢谢!我读过FormWizard,但我不知道如何过滤第二种形式的选择:( – maksymov 2011-04-26 19:45:05

回答

4

我已经在Django和其他环境中做了这个。我最近完成的方式是:只做最小数量的字段。收集这些在表格的第一页。当用户提交(我建议在重定向后发布)时,将它们存储在数据库中,然后在第二个表单上显示其余的字段。

我在注册表格中使用它。第一步创建账户。长注册表会阻止用户。如果他们没有完成第二步,那不是一个可怕的失败者。我知道他们是谁,他们以后可以完成其余的工作。如果他们完成第2步,然后我做更新并添加额外的非必填字段。 (哦,并通过“不需要”我的意思是分贝允许空)

另一个选项,我不建议将变量存储在会话中。问题在于,有时会话在用户完成表单之前超时。嘘。

比这更好的方法是将第二步隐藏字段中第一步的字段保留。

在这两种后来的情况下,如果用户离开你什么都没有。也许这对你的用例来说没问题。

+0

好,以及如何做到这一点?我的意思是最后一种方式(保持第二步隐藏字段中第一步的字段)?我可以用FormWizard做这件事吗?你可以举一个forms.py的例子吗? – maksymov 2011-04-28 07:49:37

+0

对不起,我不知道如何用FormWizard做,我只需手工制作表格。 – newz2000 2011-04-29 15:00:00

0

您可以使用FormWizard进行此操作。实施说明在Django Docs上进行了非常清楚的说明。总结一下,首先创建表示每个步骤的表单。在你的情况下,你的GenreBook型号可能是ModelForm。然后定义一个WizardView的子类,它定义了如何使用done方法处理最终数据。例如:

from django.http import HttpResponseRedirect 
from django.contrib.formtools.wizard.views import SessionWizardView 

class BookWizardView(SessionWizardView): 
    def done(self, form_list, **kwargs): 
     create_book_form_data(form_list).save() 
     return HttpResponseRedirect('/page-to-redirect-to-when-done/') 

然后,在向导中为表单创建一个模板。该模板必须位于formtools/wizard/wizard_form.html处,或者位于您覆盖template_name属性的位置,或位于重写的get_template_names方法返回的位置。最后,你勾你的观点,以传递代表在向导中的步骤表单类的实际列表中的URL配置:

from django.conf.urls import patterns 

from myapp.forms import GenreForm, BookAuthorForm 
from myapp.views import BookWizardView 

urlpatterns = patterns('', 
    (r'^contact/$', BookWizardView.as_view([GenreForm, BookAuthorForm])), 
) 
0

我强烈第二newz2000的在formWizard方法。最重要的原因是,正如newz2000所说的那样,不要丢失他们已经填写的用户的重要信息,比如说,如果他们失败了,比如说,多步骤的最后一个表格。其次,你不需要沉迷于形式魔术的额外复杂性,但它仍然不能很好地保存你 - 你仍然必须定义单独的表单,处理所有的字段并且为表单向导提供多个模板。

第三,您有能力使用fields.keyorder来呈现每个表单中的字段(确保始终发送实例,如果存在的话)的模型表单的优势。

我用newz2000的方法看到的唯一缺点是,如果你甚至可以这么称呼它,那就是你不能在模型级执行强制字段来处理后面步骤中出现的那些字段,并且他们需要在表单级完成。

另一个潜在的错误(但这很容易处理)是,如果你的模型对象的应用程序逻辑有一些依赖的其他必填类型字段,可能会留下空缺,但你应该检查这些空的条件在对它们进行操作之前,在视图/函数中仍然有字段我们甚至可以将一个“status_complete”类型字段添加到存储多值表单所完成的步骤级别的值(例如1,2,3)的模型中。然后这可以用于条件代码分支以向用户建议形式完成提醒,或者如果需要的话提供清理操作。