【问题标题】:Django: multiple table inheritance doesnt allow me to access derived class from base classDjango:多表继承不允许我从基类访问派生类
【发布时间】:2012-02-17 20:53:20
【问题描述】:

我想从实例化的基础模型类中获取派生模型类实例。

我有以下模型类层次结构:

class AlfrescoPFCModel(models.Model):
    #some fields and methods
    class Meta:
        abstract = True


class Contenido(AlfrescoPFCModel):
    #some fields and methods

class Proyecto(Contenido):
    #some fields and methods

class ProyectoCalificado(Proyecto):
    #some fields and methods

class ProyectoArchivado(ProyectoCalificado):
    #some fields and methods

我以这种方式实例化一个 Proyecto 类:

proyecto = proyecto_form.save(commit=False)
#do some stuff with some fields that dont appear on the form
proyecto.save

在另一个视图中,我尝试从之前实例化并保存在数据库中的基类 Proyecto 访问派生类 ProyectoCalificado:

pc = ProyectoCalificado.objects.get(pk=id)

我得到:ProyectoCalificado 匹配查询不存在。

我也试过了:

p = get_object_or_404(Proyecto, id=id)
pc = p.proyectocalificado

但它在第二行得到同样的错误。

阅读文档我应该被允许这样做: #multi-table-inheritance

我想做的是按照以下工作流程逐步完成与 Proyecto(项目)关联的数据:Proyecto -> ProyectoCalificado -> ProyectoArchivado。 每个步骤我有 3 种不同的表格。我需要 3 个不同的模型,因为我需要将它们保存在数据库中,而不是一次填写所有必填字段。

谢谢!

【问题讨论】:

    标签: django inheritance models base


    【解决方案1】:

    如果你有子实例,它应该有一个<base class name>_ptr 成员指向它的超类的实例。您可以使用它作为filter 查询的基础来检索孩子。

    如果您没有采取任何措施影响 id 的分配方式,您也可以假设基类和派生类的实例具有相同的 id

    【讨论】:

    • 谢谢!我有基本实例,而不是子实例,我假设是这样,但是查询 pc = ProyectoCalificado.objects.get(pk=id) (作为基类的 id)没有得到任何东西
    【解决方案2】:

    使用表单向导 (https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/)。

    更新

    如果由于您描述的情况而无法使用表单向导,那么您应该在数据库级别将模型字段设为空白或可为空,然后仅对每个单独的表单强制执行字段要求。仅为了创建它所需的单次表单集而创建三层继承绝对是错误的方法。它只会将您的数据分散到其他表中,并使查询更加复杂,没有长期利益。

    所以,例如。设置模型本身,就好像什么都不需要(或只需要第一种形式的项目)。然后,在您的第一个表单中,只填写该特定阶段所需的字段。您可以通过覆盖__init__ 轻松做到这一点:

    class FirstForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super(FirstForm, self).__init__(*args, **kwargs)
    
            self.fields['some_required_field'].required = True
            # rinse and repeat
    

    在您的第二个和第三个表单中执行相同的操作,再次填写该特定表单所需的实际字段,必填。

    那么,结束一天,喝一杯吧。

    【讨论】:

    • 谢谢,但不能使用它们,因为表格是由不同的人在不同的日子提交的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 2012-05-14
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多