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

9

是否可以为模型的子类使用不同的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"

我使用mixin的原因是我有一些属性/选择可以在不同的模型之间共享(例如,也有女士/男士裤子,它们可能具有与T恤相同的颜色选择,但尺码选择不同)。然而,总体而言,所有服装都有颜色和尺码。

我应该如何做到这一点?

2个回答

5

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


好的,谢谢 - 我得从父级中移除这个字段 :-) - Lexo
4
这是否仍然正确?如果基类是抽象的或选择来自函数,会发生什么? - AncientSwordRage
它必须是可迭代的,而函数则不是。 - byashimov

4
混合(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',
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接