Aidan Ewen
Aidan Ewen

Reputation: 13328

Access parent fields in a django model's init method

I want to access the inherited fields of a model from within that models init function -

class Parent(models.Model):
    parent_field = models.TextField(default="parent text")

    class Meta:
        abstract = True

class Child(Parent):

    def __init__(self, *args, **kwargs):
        super(Child, self).__init__(*args, **kwargs)
        self.parent_field.default="child text"

However when I try and initialize a Child object, self.parent_field (in the code above), is already a unicode object rather than a field object.

I know I'm not supposed to be overriding fields. I guess I'd need to override something in the meta class. Is there a way of doing this? Or am I just making trouble?

Upvotes: 5

Views: 6389

Answers (3)

dalang
dalang

Reputation: 111

use _meta.get_field as below:

class Child(Parent)
    def __init__(self, *args, **kwargs):
        super(Child, self).__init__(*args, **kwargs)
        self._meta.get_field('parent_field').default="child text"

Upvotes: 2

mderk
mderk

Reputation: 794

You are confusing model data with model metadata. Fields belong to the metadata. They are used at loading & saving data. The model's properties, on the contrary, are always data. That's why self.parent_field is a unicode object. To access the field objects, you need to access the model's metadata, namely self._meta object (that's where all the stuff from the class Meta also goes). The fields are in self._meta.fields, which is a list of django.models.Field objects defined for the class.

Upvotes: 9

Aidan Ewen
Aidan Ewen

Reputation: 13328

OK my tested and working code -

class Parent(models.Model):
    parent_field = models.TextField(default="parent default")

    class Meta:
        abstract = True


class Child(Parent):

    def __init__(self, *args, **kwargs):
        for f in self._meta.fields:
            if f.attname == "parent_field":
                f.default = "child default"
        super(Child, self).__init__(*args, **kwargs)

Thanks to mderk.

Upvotes: 1

Related Questions