Django 代理模型如何添加字段?
我正在写一个类似报纸的Django应用程序。我有一些文章,还有一些在特定情况下显示的定制版本的文章。比如,我可能会有一篇文章的版本,它出现在报纸的首页上,并且标题比原来的短一些。所以,我有:
class Article(models.Model):
""" A newspaper article with lots of fields """
title = models.CharField(max_length=255)
content = models.CharField(max_length=255)
# Lots of fields...
我想要一个CustomArticle
对象,它是Article
的一个代理,但可以有一个可选的替代标题:
class CustomArticle(Article):
""" An alternate version of a article """
alternate_title = models.CharField(max_length=255)
@property
def title(self):
""" use the alternate title if there is one """
if self.custom_title:
return self.alternate_title
else:
return self.title
class Meta:
proxy = True
# Other fields and methods
可惜的是,我不能在代理中添加新的字段:
>>> TypeError: Abstract base class containing model fields not permitted for proxy model 'CustomArticle'
所以,我可以这样做:
class CustomArticle(models.Model):
# Other methods...
original = models.ForeignKey('Article')
def __getattr__(self, name):
if hasattr(self.original):
return getattr(self.original, name)
else:
return super(self, CustomArticle).__getattr__(name)
但是不幸的是,__getattr__
似乎在Django模型中不起作用。因为Article
类中的字段可能会改变,所以在CustomArticle
中为每个字段创建一个@property
方法并不实际。那么,正确的做法是什么呢?
3 个回答
1
你有没有想过把CustomArticle变成Article的一个子类呢?Django的模型是支持继承的!你可以看看这个链接了解更多信息:https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance
1
试试这样做:
class CustomArticle(models.Model):
# Other methods...
original = models.ForeignKey('Article')
def __getattr__(self, name):
return getattr(self.original, name)
3
看起来这个方法可能适用于 __getattr__
:
def __getattr__(self, key):
if key not in ('original', '_ original_cache'):
return getattr(self.original, key)
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, key))