寻找一种方法,将相关的Django模型分配给抽象模型中声明的泛型关系,其他模型派生自。
Bellow是我尝试为cartridge.shop.models.Priced
抽象模型衍生的所有后代添加 ManyToOne 关系:
# 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
# my_application.models module
from cartridge.shop.models import Priced, Product
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext_lazy as _
# Simple example of a django model I wish make ForeignKey
# relationship to from all descendants of Priced model
class VAT(models.Model):
description = models.CharField(blank=False, null=False, max_length=36)
rate = models.DecimalField(
blank=False, null=False, decimal_places=2, max_digits=2+3)
class Meta:
verbose_name = _("Value Added Tax")
verbose_name_plural = _("Value Added Taxes")
Priced.vat_contype = models.ForeignKey(ContentType)
Priced.vat_id = models.PositiveIntegerField()
Priced.vat = GenericForeignKey('vat_contype', 'vat_id')
Product.vat = VAT() # Specify the concrete model here ? This way ?
我也不确定这是如何解决抽象模型后代的ForeignKey
关系的正确方法。我是否做了不必要的过于复杂的事情?可以用一个ContentType
来解决,而不是GenericForeignKey
所有{{1}}其他方式?
我知道子类化和多表继承,但我真的希望避免创建额外的表,其中简单和更快的列添加至少也是如此。
答案 0 :(得分:0)
我对你的目标有点不清楚。但是,如果您只想将所有Priced
个后代连接到VAT
,那么不需要ContentTypes。我建议您继承Priced
而不是猴子修补它,因为抽象模型不会创建数据库表。然后标记Priced
子类摘要,并将ForeignKey添加到VAT,如下所示:
# 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
就是这样。
您可以查看有关如何将新对象或现有对象关联在一起的文档here和here。
另一方面,如果您想要将所有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
ContentType API提供了各种方法来创建这些类型的对象之间的通用关系。