Django proxy model with additional model fields?
I'm writing a Django app that works like a newspaper. I have articles and then I have customized versions of those articles that appear in certain contexts. So, I could have a version of an article that appears on the front page of the newspaper that has a shorter version of the article's original headline. So I have:
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...
I'd like to have a CustomArticlè object that is a proxy for the
Articlè, but with an optional alternative headline:
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
Unfortunately, I can't add new fields to a proxy:
>>> TypeError: Abstract base class containing model fields not permitted for proxy model 'CustomArticle'
So, I could do something like this:
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)
But unfortunately, __getat开发者_JAVA技巧tr__
doesn't seem to work with Django models. The fields in the Article
class could change, so it isn't practical to create a @property
method for each one in CustomArticle. What is the right way to do this?
It looks like this might work for the __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))
What about making CustomArticle a subclass of Article? Django models do support inheritance! Have a look at: https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance
try something like this:
class CustomArticle(models.Model):
# Other methods...
original = models.ForeignKey('Article')
def __getattr__(self, name):
return getattr(self.original, name)
精彩评论