Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Can I alter construction of field defined in abstract base model for specific child model?

I am adding a slug to all my models for serialization purposes, so I have defined an abstract base class which uses the AutoSlugField from django_autoslug.

class SluggerModel(models.Model):
    slug = AutoSlugField(unique=True, db_index=False) 

    class Meta:
        abstract=True

I also have a custom manager and a natural_key method defined, and at this point I have about 20 child classes, so there are several things that make using an abstract base model worthwhile besides just the single line that defines the field.

However, I want to be able to switch a few of the default arguments for initializing the AutoSlugField for some of the child models, while still being able to utilize the abstract base class. For example, I'd like some of them to utilize the populate_from option, specifiying fields from their specific model, and others to have db_index=True instead of my default (False).

I started trying to do this with a custom Metaclass, utilizing custom options defined in each child Model's inner Meta class, but thats become a rat's nest. I'm open to guidance on that approach, or any other suggestions.

like image 573
B Robster Avatar asked Feb 26 '13 20:02

B Robster


1 Answers

One solution would be to dynamically construct your abstract base class. For example:

def get_slugger_model(**slug_kwargs):
    defaults = {
        'unique': True,
        'db_index': False
    }
    defaults.update(slug_kwargs)

    class MySluggerModel(models.Model):
        slug = AutoSlugField(**defaults)

        class Meta:
            abstract = True

    return MySluggerModel


class MyModel(get_slugger_model()):
    pass


class MyModel2(get_slugger_model(populate_from='name')):
    name = models.CharField(max_length=20)
like image 70
Daniel Naab Avatar answered Oct 21 '22 05:10

Daniel Naab