Extending an abstract class: Cannot use defined field as prepopulated_fields

I was trying to refactor my models to reuse the code for defining and saving slugs like so:

class SlugMixin:
    slug = models.SlugField(null=True, blank=True)

    def save(self, *args, **kwargs):
        # Take the __str__ output and slugify it
        self.slug = slugify(self)
        super().save(*args, **kwargs)

    class Meta:
        abstract = True

...

class SomeModel(SlugMixin, models.Model):
    name = models.CharField(...

   def __str__(self):
       return self.name

    ...

And in my admin.py Iā€™m trying to:

class SomeModelAdmin:
    prepopulated_fields = {"slug": ("name",)}

However, Iā€™m getting this error:

<class ā€˜someapp.admin.SomeModelAdminā€™>: (admin.E027) The value of ā€˜prepopulated_fieldsā€™ refers to ā€˜slugā€™, which is not a field of ā€˜someapp.SomeModelā€™.

If I move the slug field definition into my model the code works as intended. I can still use the SlugMixin and its save method from the mixin, but defining the actual slug field definition right in the mixin makes the admin code reject it with the error. Am I doing something wrong or is this an actual bug?

A parent abstract model class is not a mixin. Your child class should only inherit from SlugMixin and not the combination of SlugMixin and Model.

1 Like

Ah, thank you! Thank makes sense. Works when inheriting directly. I was refactoring the ā€œmixinā€ with just the save method but forgot about the model definitions with the multiple inheritance.