1

我在表单保存时遇到了这个问题,数据需要保存在某个地方,然后通过付款流程,然后成功检索数据并保存到正确的模型。

我已经看到使用会话完成了这项工作,但是使用一些 hacky 方法来保存文件上传,commit=False而且它看起来不是很 Pythonic

我在想如果我有一个模型类A,并且有一个扩展A的子类,例如A_Temp

class A(models.Model):
  name = models.CharField(max_lenght=25)
  image = models.ImageField()

class A_Temp(A):
  pass

class AForm(forms.ModelForm):
  class Meta:
    model = A_Temp

在模型表单(A_Temp)保存时,它存储到A_Temp,当支付成功时,将实例移动到父模型类A。

以下是问题:

  1. 有没有人这样做过?

  2. 如何正确地将子模型类的实例移动到父模型类?

编辑:

还有其他不同的方法可以做到这一点,例如向表中添加额外的字段,是的,如果我在没有 ORM 框架的情况下使用 PHP,我会这样做,但由于 ORM 在 django 中相当不错,我想我可能会尝试不同的东西。

既然我在这里问,意味着我也不相信这种方法。你觉得呢?你有没有什么想法?

4

1 回答 1

0

正如问题评论中所建议的,向包含付款状态的模型添加一个额外的字段可能是最简单的方法。从概念上讲,它是同一个对象,只是付款后状态会发生变化。正如您所指出的,您将需要逻辑来从数据库中清除永远不会通过所需状态(例如付款)的项目。这可能涉及将 apayment_statestate_change_time字段添加到模型中,以指示状态上次更改的时间。如果状态PAYMENT_PENDING时间过长,则可能会清除该记录。

如果您按照建议将未付费项目存储在不同的表中,您仍然必须管理该表以确定何时可以安全地删除项目。例如,如果从未处理过付款,您何时会从A_temp表中删除记录?此外,拥有一个单独的表意味着您实际上只有两种可能的状态,已付款和未付款,这取决于记录所在的表。拥有一个带有 a 的表payment_state可能更灵活,因为它允许您根据需要扩展状态。例如。假设您决定需要付款状态ITEM_SUBMITTED, AWAITING_PAYMENT, PAYMENT_ACCEPTED, PAYMENT_REJECTED。这都可以用一个state字段来实现。如果按照您的描述实施,则每个州都需要一个单独的表。

说了这么多,如果你仍然想拥有一个单独的表结构,你可以创建一个函数,它将值从A_tempto的实例复制A。像下面这样的东西可能会起作用,但是任何关系类型的字段ForeignKey都可能需要特别注意。

def copy_A_temp_to_A(a, a_temp):
    for field_name in a._meta.fields:
        value = getattr(a, field_name)
        setattr(a_temp, field_name, value)

当您需要从A_tempto移动时A,您必须实例化一个A实例,然后调用复制函数、save该实例并A_temp从数据库中删除该实例。

于 2013-05-27T11:35:58.843 回答