Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django&;抽象模型中的GenericForeignKey?_Python_Django_Django Models_Mezzanine - Fatal编程技术网

Python Django&;抽象模型中的GenericForeignKey?

Python Django&;抽象模型中的GenericForeignKey?,python,django,django-models,mezzanine,Python,Django,Django Models,Mezzanine,寻找一种方法,在何处以及如何正确地将相关的Django模型分配给抽象模型中声明的泛型关系,其他模型从中派生。 下面是我试图为所有派生自cartridge.shop.models.Pricedabstractmodel的后代添加多通关系的尝试: # cartridge.shop.models unit # This is a 3rd party module I can't alter sources directly. # Only monkeypatching or sublclassing

寻找一种方法,在何处以及如何正确地将相关的Django模型分配给抽象模型中声明的泛型关系,其他模型从中派生。 下面是我试图为所有派生自
cartridge.shop.models.Priced
abstractmodel的后代添加多通关系的尝试:

# cartridge.shop.models unit
# This is a 3rd party module I can't alter sources directly.
# Only monkeypatching or sublclassing are options.
from django.db import models

class Priced(models.Model):
    """
    Abstract model with unit and sale price fields. Inherited by
    ``Product`` and ``ProductVariation`` models.
    """

    unit_price = fields.MoneyField(_("Unit price"))

    class Meta:
        abstract = True

# Product derives from abstract Priced model
class Product(Priced, …):
    pass

我也不确定这是解决抽象模型子体的
ForeignKey
关系的正确方法。我是否让事情变得不必要的过于复杂?如果不使用所有的
GenericForeignKey
cruft,可以使用单个
ContentType
解决吗?其他方式


我知道子类化和多表继承,但我真的希望避免创建额外的表,因为简单、快速的列添加至少也能起到作用。

我对您的目标有点不清楚。但是,如果您只想将所有
Priced
子体连接到
VAT
,那么您不需要内容类型。我建议您将
Priced
子类化,而不是通过猴子修补,因为抽象模型不会创建数据库表。然后标记
Priced
子类abstract,并向VAT添加一个ForeignKey,如下所示:

# models.py
class VAT(models.Model):
    ...

class PricedWithVAT(Priced):
    vat = models.ForeignKey('VAT')

    class Meta:
        abstract = True

# This class will have a foreign key to VAT
class Product(PricedWithVAT, …):
    pass
就这样

您可以查看文档以及如何将新对象或现有对象关联在一起

另一方面,如果您想将所有
Priced
子体一般地连接到各种模型,那么您确实想使用ContentTypes。这并不复杂:

# models.py
class VAT(models.Model):
    ...

class PricedWithGenericRelation(Priced):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()

    class Meta:
        abstract = True

# This class can have a foreign key to ANY model, not just VAT
class Product(PricedWithGenericRelation, …):
    pass

提供了各种方法来创建这类对象之间的通用关系。

感谢您的回复。我已经有了对基本抽象类
Priced
进行子类化的想法,但是如果我没有弄错的话,我还需要创建一个新的派生产品模型,该模型将创建一个新表。但这正是我一直试图避免的。我正在研究如何通过添加一些额外的字段来调整框架的模型-不替换它们,也不通过子类化来构建十分之一的额外表,只针对那些额外的字段,这将导致额外的db连接和更慢的总体性能。我在Django方面相对较新。在Rails中,通过调整
class\u eval
块中的原始模型并生成添加新字段的简单迁移,可以非常简单地解决此问题。没有冲突,没有无意义的复杂。抽象模型不创建数据库表。例如,在我上面给出的第一段代码中,将为Product创建一个表,其中包含Product继承和定义的所有字段。PricedWithVAT将不会有数据库表,也不会有我认为你的意思那样的无关db联接。如果从最初的问题看不清楚,我想向现有框架的模型添加一个字段,即to
cartridge.shop.model.Product
,它(作为额外细节)源自抽象
cartridge.shop.model.Priced
。框架的源代码不能直接更改。通过创建自己的衍生产品模型,我希望避免创建新表。好的,是的,我认为这里有一些混乱。在这种情况下,我不清楚您的问题,因为它询问如何为抽象定价模型的所有后代添加(可能是通用的)多通关系。也许这个问题需要澄清和改写?
# models.py
class VAT(models.Model):
    ...

class PricedWithGenericRelation(Priced):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()

    class Meta:
        abstract = True

# This class can have a foreign key to ANY model, not just VAT
class Product(PricedWithGenericRelation, …):
    pass