django在父模型类和子模型类之间保存实例

django在父模型类和子模型类之间保存实例,django,inheritance,model,Django,Inheritance,Model,我在表单保存时遇到了这个问题。数据需要保存在某个地方,然后通过付款流程,然后成功检索数据并保存到适当的模型 我已经看到了使用session来实现这一点,但是在commit=False时使用了一些黑客方法来持久化文件上传,而且它看起来不太像pythonic 我在想,如果我有一个模型类a,并且有一个扩展a的子类,比如a_Temp class A(models.Model): name = models.CharField(max_lenght=25) image = models.Image

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

我已经看到了使用session来实现这一点,但是在
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

以下是问题:

  • 以前有人这样做过吗

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

  • 编辑:

    还有其他不同的方法可以做到这一点,比如在表中添加额外的字段,是的,如果我使用PHP而没有ORM框架,我会这样做,但是由于ORM在django中非常不错,我想我可能会尝试一些不同的方法


    因为我在这里问,这意味着我自己也不相信这种方法。您的想法是什么?

    正如问题评论中所建议的,在模型中添加一个包含付款状态的额外字段可能是最简单的方法。从概念上讲,它是同一个对象,只是一旦付款,状态就会改变。正如您所指出的,您将需要逻辑从数据库中清除那些从不经过所需状态(如付款)的项目。这可能涉及将
    付款状态
    状态(更改)时间
    字段添加到模型中,以指示状态上次更改的时间。如果状态为
    PAYMENT\u PENDING
    的时间过长,则可能会清除该记录

    如果按照您的建议将未付款项存储在不同的表中,您仍然需要管理该表以确定何时可以安全地删除项目。例如,如果从未处理过付款,您将何时从
    a_temp
    表中删除记录?另外,拥有一个单独的表意味着您实际上只有两种可能的状态,即根据记录所在的表确定的付费和未付费状态。使用带有
    付款状态的单个表可能更灵活,因为它允许您根据需要扩展状态。例如,假设您决定您需要付款状态
    已提交的项目
    等待付款
    已接受付款
    已拒绝付款
    。这一切都可以通过一个
    状态
    字段来实现。如果这是如您所描述的那样实现的,那么每个状态都需要一个单独的表

    话虽如此,如果您仍然设置为使用单独的表结构,则可以创建一个函数,将值从
    a_temp
    的实例复制到
    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_temp
    移动到
    A
    时,必须实例化
    A
    实例,然后调用复制函数,
    保存
    实例并从数据库中删除
    A_temp
    实例。

    我假设支付过程需要在正常的django请求/响应周期之外进行?是否可以向类A添加一个附加字段并对其进行更新,而不是在A和A_temp之间来回移动?这是我的另一种方式最初我也是这么想的。我之所以尝试添加字段,是因为当我们有额外的字段来通知记录时,表可能包含无用的记录,在大数据范围内,需要创建索引来保持性能和清理。另一方面,本例中的temp模型作为沙盒执行感谢您的冗长回答,是的,我知道我也需要清除temp表。这个想法可能看起来很愚蠢,我在这里问这个问题的原因是因为我想要一个尽可能干净的表,对于不同的状态,额外的字段也可以添加到一个临时模型中。我想创建数据库视图来分割列表可能是在同一模型中具有额外字段的另一种选择。数据库视图可能是解决“清理”问题的一种方法,但这也有其自身的问题。例如Django不支持数据库视图,因此无法在单元测试期间创建视图。并不是所有的数据库后端都支持db视图,例如sqlite。尽管如此,还是有可能做到这一点(我也使用了这种方法)。您的db视图模型可以设置
    class Meta:managed=False db\u table=
    。实现只返回付费项目的自定义管理器也可能很有用。例如,不要使用
    A.objects.all()
    ,而是使用
    A.paid\u objects.all()
    。或者,重写
    对象
    默认管理器以仅返回付费实例。这是一种冗长的方法