django模型中的硬编码属性

时间:2016-02-09 11:00:16

标签: python django database-design django-models

好的,这是其中一个在我脑海中完全有道理但很难解释的问题:)我有一个django应用程序,我想存储许多不同设备的记录。每种类型的设备都有一个自定义模型来存储其属性,例如下面的MyEquipment。每种类型的设备也都有一个“类别”,这对于存储属性非常有用。

class Category(models.Model):
    code = models.CharField('Category', max_length=4, unique=True)
    description = models.CharField('Description', max_length=30)
    ...

class MyEquipment(models.Model):
    serial = models.IntegerField()
    ...

要将此属性保存到我的模型,我可以使用Category的外键,但我不需要,因为MyEquipment中的每个记录都必须相同Category。那么我想也许我可以像这样在Category元中对MyEquipment进行硬编码:

class MyEquipment(models.Model):
    serial = models.IntegerField()
    ...

    class Meta:
        category = Category.objects.get(code='EC')

但是,这将依赖于填充数据的Category模型来构建MyEquipment模型。对我来说,这似乎不是最佳实践,使用可能存在或不存在的数据来定义另一个模型的结构。是否有更好的方法来设置与Category模型相关的MyEquipment

修改

感谢下面的讨论,这让我意识到也许我在原帖上并不清楚。所以我想要做的是将MyEquipmentCategory联系起来。所以我可以这样做:

>>> from myapp.models import MyEquipment
>>> MyEquipment.CATEGORY
<Category: EC>

我想将整个模型链接到Category,因此我可以在视图中以不同的方式处理每个模型,具体取决于它的类别。在考虑了这个问题之后,我可以通过写MyEquipment来获得这个功能:

class MyEquipment(models.Model):
    CATEGORY = Category.objects.get(code='EC')

    serial = models.IntegerField()
    ...

这种方式有效,但这是最好的方法吗?我想模型会在每次实例化类时执行此操作吗?有更有效的方法吗?

2 个答案:

答案 0 :(得分:2)

无论如何你不能这样做; Meta类不支持任意属性。

最好的办法是将其定义为属性,您可以通过实例本身访问该属性。为了提高效率,你可以在课堂上记忆它。

@property
def category(self):
    _category = getattr(self, '_category', None)
    if not _category:
        self.__class__._category = _category = Category.objects.get(code='EC')
    return _category

答案 1 :(得分:0)

but ... every record in MyEquipment must be the same Category

然后你不需要任何关系。正如您所说,MyEquipment中的每条记录都是相同的类别,为什么要在db中存储关系?

UPD:具有模型继承的解决方案

class Place(models.Model):
    category = models.ForeignKey(Category)
    class Meta:
         abstract = True

    def save(self, *args, **kwargs):
        self.category = Category.objects.get(name=self.CATEGORY)
        return super(Place, self).save(*args, **kwargs)

class Restaurant(Place):
    ...fields...
    CATEGORY = 'RE'

class Building(Place):
    ...fields...
    CATEGORY = 'BU'