David542
David542

Reputation: 110502

Make generic model save method

I have the following save method for the Catalog model:

class Catalog:
    ...
    def save(self, *args, **kwargs):
        if not self.pk:
            log.error('NOT ALLOWING SAVE OF %s' % self.__class__.__name__)
        else:
            super(Catalog, self).save(*args, **kwargs)

Is there a way to make:

super(Catalog, self).save(*args, **kwargs)

More generic, so I don't have to hardcode Catalog in there, and I can use this for any model without any modification?

Upvotes: 2

Views: 158

Answers (2)

Daniel Roseman
Daniel Roseman

Reputation: 600041

You shouldn't be copying and pasting code between classes. That misses the whole point of the vital principle of Don't Repeat Yourself (DRY).

Instead, make this a method on a separate class which you can use as a mixin.

class SavePrevented(object):
    ...
    def save(self, *args, **kwargs):
        if not self.pk:
            log.error('NOT ALLOWING SAVE OF %s' % self.__class__.__name__)
        else:
            super(SavePrevented, self).save(*args, **kwargs)

and use it when you define any other model:

class Catalog(SavePrevented, models.Model):
    ...

Upvotes: 0

David542
David542

Reputation: 110502

One option is to create a pre_save function that will error on any of those models.

from django.db.models.signals import pre_save
from django.dispatch import receiver
@receiver(pre_save)
def refuse_creation(sender, instance, *args, **kwargs):
    FORBIDDEN_MODELS = ['Table1', 'Table2', ...]
    cls_name = instance.__class__.__name__
    if cls_name in FORBIDDEN_MODELS:
        if not instance.pk:
            log.error('REFUSING TO CREATE OBJECT FOR %s' % cls_name)
            raise

Upvotes: 2

Related Questions