Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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, __getattr__ 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?

like image 802
Joshmaker Avatar asked Aug 19 '11 18:08

Joshmaker


People also ask

What is Verbose_name in Django?

verbose_name is a human-readable name for the field. If the verbose name isn't given, Django will automatically create it using the field's attribute name, converting underscores to spaces. This attribute in general changes the field name in admin interface.

How do I create a one to many relationship in Django?

To handle One-To-Many relationships in Django you need to use ForeignKey . The current structure in your example allows each Dude to have one number, and each number to belong to multiple Dudes (same with Business).

What is proxy model inheritance in Django?

The main Usage of a proxy model is to override the main functionality of existing Model. It is a type of model inheritance without creating a new table in Database. It always query on original model with overridden methods or managers.

WHAT IS models CharField in Django?

CharField is a commonly-defined field used as an attribute to reference a text-based database column when defining Model classes with the Django ORM. The Django project has wonderful documentation for CharField and all of the other column fields.


1 Answers

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))
like image 67
Joshmaker Avatar answered Sep 28 '22 05:09

Joshmaker