Thursday, August 30, 2012

Overriding a Field attribute in a proxy model is not allowed.

Hello, 

I'm currently working with an app that i would not like to modify.

This app contains 2 Models, basically : (i took off some code to make it clearer)

```
class Invoice(models.Model):
   [...] a bunch of attributes [...]
   lines = generic.GenericRelation(Line)
   
   [...] all the class methods [...]

class Line(models.Model):
   content_type [...]
   [...] a bunch of attributes [...]

   product = models.ForeignKey(Product)
   price = models.DecimalField()
   quantity = models.IntegerField()
   [...] all the class methods [...]

```

I would like to add only method computing the values of these models to use it elsewhere (another app).
So no table in database, need to add methods and do not want to modifiy the original class, the documentation seems to indicate the model proxy.

So i'm going with something like this in a different app :

```
class PackingList(Invoice):
    lines = generic.GenericRelation(PackingListLine)

    def get_number_of_boxes(self):
        total = 0
        for line in self.lines.all():
            total += line.get_number_of_boxes()
        return total

    class Meta:
        proxy = True


class PackingListLine(Line):
    def get_number_of_boxes(self):
        if self.product.quantity_per_box:
            return self.quantity / self.product.quantity_per_box

    class Meta:
        proxy = True

```

But Django raise a beautiful ```django.core.exceptions.FieldError: Proxy model 'PackingList' contains model fields.```.
Normal ! It is clearly specified in the docs, it is forbidden to override a field attribute in a Django Model.

So i understand the need to restrict the usage of these manipulation to not break the framework internal mechanisms, but i don't know in this case which other approach would be best (Minimal model with one2one relationship ? everything in a view class ? separate my code in a different class/file that i would call individually ? triggers ? make an intermediate class that would get the instance ?).

My question is, what is the clean way to code this ?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/4QK6OGtwP5cJ.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment