首页 文章

在Django中动态添加表单到formset并使用AJAX提交

提问于
浏览
0

我已经阅读了很多关于如何在Django中动态添加表单到模型formset的答案,并且可以成功地实现它 . 但是,我现在想用AJAX提交formset . 这主要是现在工作,但我有一个问题,我找不到任何其他答案的解决方案:

如果您动态地向表单集添加表单,则为其提供一个新表单标识号,该表单标识号大于当前表单的最大值,并且还将管理TOTAL_FORMS计数增加1 . 然后,新添加的表单将成功保存为新对象 .

我试图通过AJAX提交,以便用户可以继续编辑而无需刷新页面 . formset保存得很好,但任何动态添加的表单现在都是现有对象 . 为了解决这个问题,我需要在保存成功时增加管理表单上的INITIAL_FORMS计数 . 很容易 . 但是,我也意识到我需要为新创建的对象提供一个ID,因为它们现在存在于数据库中 .

如何让我的视图在响应AJAX调用时告诉我新对象的ID?或者有更好的方式来看待这个?

2 回答

  • 0

    Django表单和表单集用于基于浏览器的经典数据发布 . 尽管它们绝对可以与Javascript一起使用,但是您希望从正常行为中分离得越多,它就越复杂 .

    根据您的要求,您可能会开始考虑删除它并切换到Javascript REST endpoints . 当然,如果您需要渐进增强功能,并且您需要在没有javascript的情况下使用它,那么这不是一个选项 .

    在任何情况下,您都希望有一个自定义视图用于从JS发布,以便您可以返回结果并在AJAX处理程序中轻松解析它 . 可能是一些JSON .

    您可以采取几种方法 .

    • 让您的AJAX将数据发送到其他URL . 如果您有API或计划在某个时刻构建一个API,这是相关的 . 因此,您的表单在正常提交时将执行旧式处理,但您的AJAX将与API endpoints 进行通信 .

    例如,您的表单发送到 https://example.com/myform ,但您的Javascript代码在 https://example.com/api/v1/mymodel/ 处与REST api进行通信(根据需要发送PUT,POST和DELETE请求) .

    • 或者如果你没有API并且构建一个似乎有点过分,你可能只是改变你的视图,因此它根据数据是以常规方式提交还是使用AJAX来不同地格式化其输出 .

    你会这样做:

    class MyFormView(.....):
        def render_to_response(self, context, **kwargs):
            if self.request.is_ajax():
                return self.render_to_json(context, **kwargs)
            return super().render_to_response(context, **kwargs)
    
        def render_to_json(context, **kwargs):
            data = {
                # see below!
            }
            return HttpResponse(
                content=json.dumps(data).encode('ascii'),
                content_type='application/json',
            )
    

    这只是一个大纲 . 您需要确保 is_ajax 能够正确检测到它(请参阅django doc) . 并且您需要从 context 正确构建 data :将要发送回JS代码的内容解压缩并将它们放入dict中 .

    你会发现's manageable if you just do this for one, maybe two views in your project, but very quickly you' ll想要一个小的API,特别是考虑到使用Django REST framework等软件包构建一个API是多么容易 .

  • 1

    在您保存对象的视图中,在保存之后,object.id将包含对象的新id,您可以通过json返回,或者您想要在ajax响应中返回,然后是,您需要填写进入formset行,以便下次提交 .

    您需要注意的一件事是,django希望所有现有行都位于formset的顶部,而任何新行都位于底部 . 否则,formset save会抱怨缺少id . 因此,如果您在javascript中进行任何类型的排序,则不能这样做..除非您在formset中对所有字段名称进行相当多的修复 . formset代码使用管理表单中的数字来确定要插入哪些行以及要更新哪些行,它不会根据是否存在id来执行此操作 . 不幸...

相关问题