3

If I would like to change e.g. Django's Site module:

from django.contrib.sites.models import Site

How would I do that in my project? Do I subclass or what do I do to change or add some code to it?

Or do I just create a new model?

bakkal
  • 54,350
  • 12
  • 131
  • 107
Y7da
  • 403
  • 2
  • 5
  • 14
  • 1
    What do you mean with "modify"? If you need to extend `Site`, subclassing is the way. – LostMyGlasses Feb 04 '16 at 10:13
  • If I where to change an existing field in the Django model. Like i comment below in bakkal's answer. – Y7da Feb 04 '16 at 10:38
  • 1
    In fact, you cannot do that: https://docs.djangoproject.com/es/1.9/topics/db/models/#field-name-hiding-is-not-permitted. – LostMyGlasses Feb 04 '16 at 10:42
  • 1
    You'll either need to subclass `Site`, leave the `name` field as already is and create a new field (say, `custom_name`), leaving the first one unused, or create your own model from scratch. – LostMyGlasses Feb 04 '16 at 10:43
  • In fact, the question has an answer [here](http://stackoverflow.com/questions/2344751/in-django-model-inheritance-does-it-allow-you-to-override-a-parent-models-a) – LostMyGlasses Feb 04 '16 at 10:49
  • OK, maybe the best solution is then to create a new Site model? @LostMyGlasses – Y7da Feb 04 '16 at 10:51
  • If you need to modify a field of `Site`, then yes, I'd do it. – LostMyGlasses Feb 04 '16 at 10:53

1 Answers1

5

You can add a field via inheritance

If you still need to keep a reference to the original Site object/row, you can use multi-table inheritance

from django.contrib.sites.models import Site

class MySite(Site):
    new_field = models.CharField(...)

    def new_method(self):
        # do something new

This allows you to have regular Site objects, that may be extended by your MySite model, in which case you can e.g. access the extra fields and methods through site.mysite, e.g. site.mysite.new_field.

Through model inheritance, you cannot alter an ancestor field

Through inheritance you cannot hide ancestor fields, because Django will raise a FieldError if you override any model field in any ancestor model.

And I wouldn't venture and write a custom DB migration for this, because then if you update Django, you may get schema conflicts with the Site model.

So here's what I would do if I wanted to store more info that the ancestor model allows:

class SiteLongName(Site):
    long_name = models.CharField(max_length=60)
bakkal
  • 54,350
  • 12
  • 131
  • 107
  • Okey, that's pretty nice. Though I still wonder if I need to change a field in the Site model that's currently: `name = models.CharField(_('display name'), max_length=50)` to change the `max_length=60` instead. How do I do that? Just add it again in the new multi-table inheritance? – Y7da Feb 04 '16 at 10:37