2016-02-09 99 views
1

好吧,这是一个在我的头上非常有意义的问题,但很难正确解释:)我有一个django应用程序,我想存储许多不同项目的记录设备。每种类型的设备都会有一个自定义模型来存储其属性,如下面的MyEquipment。每种类型的设备也会有一个“类别”,这对于存储属性很有用。django模型中的硬编码属性

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。于是我想也许我可以硬编码在MyEquipment元这样的Category

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

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

但随后这将依赖于Category模型被填充了数据建立模型MyEquipment。对我来说,这似乎并不是最好的做法,使用可能存在或可能不存在的数据来定义另一个模型的结构。有没有更好的方法来设置MyEquipment模型与哪个Category相关?

编辑

感谢下面的讨论中,它使我意识到也许我是不是在我原来的职位明确。所以我想要做的就是将MyEquipment链接到Category。所以,我可以做这样的事情:

>>> 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

反正你不能这样做; Meta类不支持任意属性。

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

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

好,谢谢,我还没有碰到过的@property装饰面前。我如何在我的用例中使用它? – DrBuck

+0

您可以直接访问它:'my_equipment_instance.category'。 –

+0

我明白了,所以我会把这个def作为MyEquipment类定义的一部分?这种方法仍然依赖于“类别”模型中的'EC'记录,这是否重要?还是不值得担心? – DrBuck

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' 
+0

你说得对,我不需要将它作为关系存储,但是如果我在所有模型中对'CATEGORY ='EC''进行硬编码,我认为它会变得有点难以管理。我也在其他地方使用'Category'模型来获得正确的ForeignKey关系,所以无论我是否使用'MyEquipment'模型,它都会存在。 – DrBuck

+0

我认为你正试图完成不同的事情,但尚未分享整个图片。假设你有'Category'模型,'Restaurant'模型只能有'RE'作为其Category,'Building'模型存储'BU'作为它的类别,等等。在这种情况下,您应该创建一个父模型,让它说'Place',而不是继承餐厅,从中建立模型,通过这样做,您将获得构建应用程序所必需的抽象,并且它们都可以指向其“类别” – ikhtiyor

+0

那么你的意思是我应该把'Category'作为一个外键加入到'Restaurant'和'Building'模型的抽象基类中?使用它,我仍然必须编写一些自定义代码来设置'Category',每次我添加'Restaurant'或'Building'不是吗?如果是这样,使用上面的方法似乎对我更好 – DrBuck