相同的字段,Django模型子类中的不同选择

时间:2011-05-06 12:05:42

标签: django django-models

是否可以对模型的子类使用不同的choices?以下代码应该给你一个想法

class Clothing(models.Model):
    size = models.CharField(max_length=1)
    colour = models.CharField(max_length=1)

SHIRT_SIZES = {
    'S','Small',
    'M','Medium',
    'L','Large',
}

class TShirt(models.Model):
    size = models.CharField(max_length=1, choices=SHIRT_SIZES)

MENS_CHOICES = {
    'K','Black',
    'R','Red',
    'B','Blue',
}

class MensColours(models.Model):
    colour = models.CharField(max_length=1, choices=MENS_CHOICES)

class MensShirt(MensColours, TShirt):
    class Meta:
        verbose_name = "men's shirt"

WOMENS_CHOICES = {
    'P','Pink',
    'W','White',
    'B','Brown',
}

class WomensColours(models.Model):
    colour = models.CharField(max_length=1, choices=WOMENS_CHOICES)

class WomensShirt(WomensColours, TShirt):
    class Meta:
        verbose_name = "women's shirt"

我使用mixins的原因是我拥有可以在不同模特之间共享的属性/选择(例如,也有女士/男士裤子,可能有相同颜色选择但尺寸选择不同于TShirts)。但总的来说,所有服装都有颜色和尺寸。

我该怎么做?

2 个答案:

答案 0 :(得分:5)

没有。潜在的字段选择在父级中是固定的。您可以通过指定表单字段的有效选项来解决此问题,但不能更改模型字段的基本属性。

答案 1 :(得分:2)

Mixins是解决此类问题的正确方法。但是如果你必须在每一个班级中让田野相互依赖,那么还有另一种方式 您必须在类的定义中定义您的字段。这意味着你必须破解课堂建设过程。因为它在创建之后就变得具体了。我真的不知道之后是否有机会改变这个领域。

from django.db import models
from django.db.models.base import ModelBase


class ApparelMeta(ModelBase): 
    def __new__(mcs, name, bases, attrs):
        meta = attrs.get('Meta', None)

        # We should check if it is the end class
        # because django's class inheritance is not pythonic
        if meta and not getattr(meta, 'abstract', None) \
            and not attrs.get('_deferred'):
            sizes = models.CharField(max_length=1, choices=attrs['SIZES'])
            colors = models.CharField(max_length=1, choices=attrs['COLORS'])

        return super(ApparelMeta, mcs).__init__(mcs, name, bases, attrs)


class Apparel(models.Model):
    __metaclass__ = ApparelMeta

    class Meta:
        abstract = True
        index_together = (
            ('sizes', 'colors'),
        )

# Now you can create all that classes: men, women, children

class MensApparel(Apparel):
    COLORS = {
        'K','Black',
        'R','Red',
        'B','Blue',
    }

    SIZES = {
        'S','Small',
        'M','Medium',
        'L','Large',
    }


class WomensApparel(Apparel):
    COLORS = {
        'R','Red',
    }

    SIZES = {
        'S','Small',
    }