代码之家  ›  专栏  ›  技术社区  ›  dr jimbob

Django保存表单上的未完成进度

  •  9
  • dr jimbob  · 技术社区  · 15 年前

    我有一个django webapp,有多个用户登录并填写表单。

    有些用户可能开始填写表单,但缺少验证表单所需的某些数据(例如,授权书(grant))(在我们开始处理表单之前)。我希望他们能够填写表格,并有一个选择,以保存部分信息(以便改天他们可以登录并完成它)或提交正在验证的完整信息。

    目前,我对所有使用的表单都使用Model for m,并且该模型具有确保有效数据的约束(例如,授权必须是唯一的)。但是,我希望他们能够保存这个中介数据,而不需要进行任何验证。

    我想到的解决方案似乎很不雅观,而且不符合实际情况:创建一个保存POST字典的“Save Partial Form”按钮,将其转换为 shelf 文件并创建一个“SavedPartialForm”模型,将用户连接到保存在工具架中的部分表单。这看起来合理吗?有没有更好的方法将POST dict直接保存到数据库中?或者是执行表单部分保存的附加模块(这似乎是webforms中相当常见的活动)?

    我对我的方法最担心的是,我希望最终能够在某些ajax/jquery方法中自动保存表单(比如每10分钟一次),而无需实际按下按钮并发送POST请求(例如,当autosave被触发时,用户不会被重定向到页面之外)。我对jquery不太熟悉,我想知道是否可以这样做。

    4 回复  |  直到 15 年前
        1
  •  8
  •   Andrew Sledge    15 年前

    有一个很好的解决方案 Pro Django by Marty Alchin . 简而言之,您可以创建另一个模型,其中包含表单的哈希值、表单字段和保存的值。恢复时,只需根据表单的哈希值加载。

        2
  •  3
  •   Bruno Gelb Roger Allen    12 年前

    保存前:

    for field in form.fields:
        form.fields[field].required = False
    

    然后:

    form.save()
    
        3
  •  1
  •   S.Lott    15 年前

    问题是你有多种表格。

    部分的。不完整。完成。准备好了。准备好了。

    实际上,工作流的每个阶段都有一个表单。

    这没什么问题。

    1. 找出你在工作流程中的位置。

    2. 填写并呈现下一阶段的表单。

    表单可以相互继承以保存重复的验证方法。

        4
  •  1
  •   SleepyCal    12 年前

    在表格中填写以下内容 __init__

    for field in form.fields:
        form.fields[field].required = False
    

    例如:

    class MySexyForm(Form):
        def __init__(self, *args, **kwargs):
            super(MySexyForm, self).__init__(*args, **kwargs)
            for field in self.fields:
                self.fields[field].required = False
    

    然后打电话给:

    form = MySexyForm(...)
    form.save()
    

    但是你需要确保 clean() 方法可以通过条件检查是否存在于清除数据中来处理任何缺失的属性。例如,如果另一个表单字段验证依赖于 customer_id 但是你的部分表格没有指定 客户id 不会出现在清除的数据中。

    如果这是一个模型表单,您可以检查该值是否在 cleaned_data ,然后退回到 instance.field 例如,如果它不见了;

    def clean(self):
        inst = self.instance
        customer_id_new = self.cleaned_data.get('customer_id', None)
        customer_id_old = getattr(self.instance, 'customer_id') if inst else None
        customer_id = customer_id_new if customer_id_new else customer_id_old
    

    记住,新值几乎肯定不会与旧值采用相同的格式,例如 客户id 实际上可能是 RelatedField 在模型实例上 int 在表单数据上。同样,您需要在clean中处理这些类型差异。

    这是Django表单真正缺少的一个方面。