Django proxy model with additional model fields?

I am writing a Django application that works like a newspaper. I have articles, and then I have customized versions of those articles that appear in specific contexts. Thus, I could have a version of the article that appears on the front page of the newspaper, which has a shorter version of the original title of the article. Therefore, 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 would like to have a CustomArticle object, which is a proxy for the article, but with an optional alternative title:

 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 cannot add new fields to the proxy:

TypeError: an abstract base class containing model fields that are not allowed for the "CustomArticle" proxy model

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 __getattr__ doesn't seem to work with Django models. Fields in the Article class can change, so it is not practical to create the @property method for each of them in CustomArticle. What is the right way to do this?

+6
source share
3 answers

How to make CustomArticle a subclass of an article? Django models support inheritance! Take a look at: https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance

+1
source

try something like this:

 class CustomArticle(models.Model): # Other methods... original = models.ForeignKey('Article') def __getattr__(self, name): return getattr(self.original, name) 
+1
source

It looks like this might work for __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)) 
+1
source

Source: https://habr.com/ru/post/895441/


All Articles