Django:如何将模型表单数据从一个页面传递到另一个页面,而不是提交到数据库? [英] Django: How to carry model form data from one page to another, and back, without commiting to the DB?

查看:2836
本文介绍了Django:如何将模型表单数据从一个页面传递到另一个页面,而不是提交到数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[序言:虽然我意识到可能会有更简单的方法来做到这一点(即,只需使用Django内置的管理员,或者使用内联在一页上进行所有的编辑等),不幸的是,我不能控制设计,所以我正在寻求帮助我如何处理我执行的任务。]

我有2模型,甲板和幻灯片。幻灯片有外键到甲板。 (还有一个中间模型 - 一个m2m的关系 - 但为了简化一个已经复杂的讨论,我将假装一个更简单的多对一关系。)

I have 2 models, Deck and Slide. Slide has foreign key to Deck. (there is also an intermediate model--its a m2m relationship--but to simplify an already complex discussion, I'm going to pretend its a simpler many-to-one relationship.)

我正在实现的界面显示一个带有表单的页面,用于输入或编辑Deck字段,其中还包含一个嵌入式列表,其中包含一些字段(我正在进行文本输入)以及每个幻灯片的编辑和删除锚链接。 (见img)如果单击编辑链接,则会转到具有详细表单的新页面,以输入表示相应幻灯片内容的所有信息。如果您单击该表单中的提交,您将返回到该卡片的页面。

The interface i am implementing displays a page with a form to enter or edit Deck fields which also includes an embedded list of Slides in the Deck, with some fields (which I'm in the process of making text inputs) and also with an "edit" and a "remove" anchor link for each Slide. (see img) If you click an "edit" link, it takes you to a new page with a detailed form to input all the information representing the content for the corresponding slide. If you click submit in that form, it takes you back to the page for the deck.

正如标题问题提出的,我显然不想在DB中提交任何Deck或幻灯片,直到用户单击提交整个Deck,即可以在临时添加或编辑许多幻灯片并可能决定取消整个过程。

As the title question proposes, I obviously don't want to commit any Deck or Slides to the DB until a user clicks Submit for the entire Deck, i.e. they can add or edit many slides in the interim and may decide to cancel the whole process.

这是最好的,最干净的方法是什么?

What is the best, cleanest way of doing this?

我看过Django的FormWizard类 http://docs.djangoproject.com/en/dev / ref / contrib / formtools / form-wizard / ),但似乎是面向多步线性流,而不是我的情况。

I've looked at Django's FormWizard class ( http://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/ ), but seems to be geared towards a multi-step linear flow, not my situation.

我已经不得不实现这个演示,我已经得到了大部分的方式,通过创建一个内联FormSet为幻灯片和甲板的表单,然后为我的Forms编写子类,隐藏窗体和表单,因为我在两个页面之间来回传递。以下是一些代码,演示了如何在幻灯片页面中使用隐藏的表单:

I already had to implement this for a demo, and I've gotten most of the way there by creating an inline FormSet for the Slides and a Form for the Deck, and then writing subclasses for my Forms that hide the form and the formset as I pass back and forth between the two pages. Here's some code demonstrating how I use a hidden form for the deck in the slide page:

class DeckForm(ModelForm):
    class Meta:
        #stuff here

class HiddenDeckForm(DeckForm):
    def __init__(self, *args, **kwargs):
        super(DeckHiddenForm, self).__init__(*args, **kwargs)
        for name, field in self.fields.iteritems():
            field.widget = field.hidden_widget()
            field.required = False

所以在我的意见中,每次我去幻灯片页面,我生成一个HiddenDeckForm从POST数据并将其传入,然后在我的视图中返回到甲板页面,我从POST数据重新生成DeckForm(不是隐藏的子类)。不会发布我所有的幻灯片表单代码,因为我基本上是询问是否有更好的方法,但是类似地,我有一个HiddenSlideForm类,并通过我的模板之间的格式保存状态。

So in my views, every time I go to the slide form page, I generate a HiddenDeckForm from the POST data and pass it in, and then in my view going back to the deck page, I regenerate the DeckForm (not hidden subclass) from the POST data. Not going to post all my Slide form code, since I'm basically asking whether there is a better way of doing it, but similarly, I have a HiddenSlideForm class, and pass a formset of those between my templates to save the state.

然后当用户点击Deck页面上的提交时,Deck表单和幻灯片表单都保存到数据库。

Then when the user clicks submit on the Deck page, the Deck form and Slides formset are all saved to the DB.

它有效,但这是一个很好的方法吗?它是一个很好的代码,我真的不得不挖掘一些Django内部 - 感觉就像我正在使用的东西,他们不是设计使用的方式。还是处理这种情况还有更标准的方法?

It works, but is this a good way to do it? Its been a good bit of code, and I've really had to dig into some Django internals--feel's like I'm using things in a way they weren't designed to be used. Or is there already a more standard way of handling this scenario?

如果有帮助,我会发布更多的代码。

I'll post more code if its helpful.

感谢您的帮助!

PS正如你所看到的,我正在一个jquery colorbox中实现它,并使用ajax进行表单之间的转换,但是我只是使用普通模板/表单在我的视图中渲染,并将渲染的html传回到带有ajax调用的页面。 。 。猜测我可以用json做一些事情,但是强烈地喜欢坚持传递一个渲染的模板,因为这样一个实现可以在没有ajax或javascript的情况下被使用。

推荐答案

通过处理formset工具,完成了非常相似的要求,我完全同意,去保护和限制来了解/定制formset是完全不值得的。

Having done the very similar requirement by working around the formset tools, I completely agree that going hoops and bounds to understand/customize the formset is totally not worth it.

对于像你这样的屏幕截图,我将只使用一个窗体,每个卡片的所有幻灯片。 - 表单,而不是formset。

For a screenshot like yours, I'd use just one form with all of the slides per deck. - Form, not formset.

您应该在ajax请求中处理幻灯片edit / delete / new,包括您在创建新甲板时创建的套牌。然后在甲板表格中,您只需更改名称和关联的 Deck 属性。

You should handle the slide "edit/delete/new" all in ajax requests that include the deck you create when someone creates a "new deck". And then in the "Deck Form", you only change the Deck properties like name and association.

或者,如果您不需要Ajax并创建新的幻灯片对象,您可以在页面本身中执行所有新元素,您可以使用 formset 并保存卡片和所有关联的幻灯片。

Or, if you are inlined to do all new elements in the page itself without Ajax and creating new "Slide" objects, you can use the formset and save the deck and all associated slides.

这篇关于Django:如何将模型表单数据从一个页面传递到另一个页面,而不是提交到数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆