2015-04-09 5 views
1

Ищете способ, в котором и как правильно назначить связанную модель Django с общим отношением, объявленным в абстрактной модели, из других моделей. пыльник моя попытка добавить ManyToOne отношения для всех потомков, вытекающих из cartridge.shop.models.Pricedабстрактной модели:Django & GenericForeignKey от абстрактной модели?

# 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 cruft? Другой путь ?

Я знаю о наследовании подклассов и множестве таблиц, но мне бы очень хотелось избежать создания дополнительных таблиц, в которых, как минимум, было бы проще и быстрее добавлять столбцы.

ответ

0

Я немного не понимаю вашу цель. Но, если вы хотите подключить всех Priced потомков к VAT, то вы не need ContentTypes. Я бы рекомендовал вам подкласс Priced вместо того, чтобы обезвреживать его, потому что абстрактные модели не создают таблицы базы данных. Затем отметьте Priced подкласса аннотацию, и добавить 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 

И это все.

Вы можете посмотреть документацию here и here о том, как связать новые или существующие объекты вместе.

С другой стороны, если вы хотите подключить всех потомков Priced к различным моделям в целом, то вы do действительно хотите использовать 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 предоставляет различные способы создания родовых отношений между этими видами объектов.

+0

Спасибо за ответ. У меня уже возникла идея подкласса базового абстрактного класса «Priced», но тогда мне также нужно было бы создать новую модель производного продукта, которая создала бы новую таблицу, если я не ошибаюсь. Но этого я и старался избегать. Я смотрю, как настраивать модели фреймворка, добавляя несколько дополнительных полей - не заменяя их и не создавая десятки дополнительных таблиц путем подкласса, просто для тех дополнительных полей, которые приведут к посторонним объединениям db и более низкой общей производительности. –

+0

Я относительно новый в Django. В Rails эта проблема решается очень просто, корректируя исходную модель в блоке 'class_eval' и создавая простую миграцию, которая добавляет новые поля. Никаких конфликтов, бессмысленных осложнений. –

+0

Абстрактные модели не создают таблицы базы данных. Так, например, в первом фрагменте кода, который я привел выше, была бы создана таблица для продукта со всеми полями, которые Продукт наследует и определяет. Не было бы таблицы базы данных для PricedWithVAT, и никакие посторонние db не объединяются так, как вы думаете. –

Смежные вопросы