Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#30080 closed New feature (wontfix)

New optional settings - disable bulk_create in all managers and call self.full_clean() before saving the models

Reported by: אורי Owned by: nobody
Component: Database layer (models, ORM) Version: 1.11
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by אורי)

We are using Django for Speedy Net and Speedy Match (currently Django 1.11.18, we can't upgrade to a newer version of Django because of one of our requirements, django-modeltranslation). I want to validate each model before saving it to the database, so I'm using class ValidateModelMixin as the base of each model.

For this reason, I want to disable bulk_create in all managers in all of our models. So I added this code:

class ValidateModelMixin(object):
    def save(self, *args, **kwargs):
        """Call `full_clean` before saving."""
        self.full_clean()
        return super().save(*args, **kwargs)


class ManagerMixin(object):
    def bulk_create(self, *args, **kwargs):
        raise NotImplementedError("bulk_create is not implemented.")


class BaseModel(ValidateModelMixin, models.Model):
    def save(self, *args, **kwargs):
        try:
            field = self._meta.get_field('id')
            if ((not (self.id)) and (hasattr(field, 'id_generator'))):
                self.id = field.id_generator()
                while (self._meta.model.objects.filter(id=self.id).exists()):
                    self.id = field.id_generator()
        except FieldDoesNotExist:
            pass
        return super().save(*args, **kwargs)

    class Meta:
        abstract = True


class TimeStampedModel(BaseModel):
    date_created = models.DateTimeField(auto_now_add=True, db_index=True)
    date_updated = models.DateTimeField(auto_now=True, db_index=True)

    class Meta:
        abstract = True


class BaseManager(ManagerMixin, models.Manager):
    pass


class BaseUserManager(ManagerMixin, DjangoBaseUserManager):
    pass


I thought maybe it's good to add these settings - disable bulk_create in all managers and call self.full_clean() before saving the models - as an optional settings both in the project and also in each model (maybe in class Meta) so it will be possible to override Django's default both per-project and also for any specific model. I understand that the default is not to call self.full_clean() before saving the models and to allow bulk_create in the managers, but I suspect this may lead to invalid data in the database of the projects.

The current code in the master is on https://github.com/speedy-net/speedy-net/blob/master/speedy/core/base/models.py, and the code in the branch I'm currently working on is on https://github.com/speedy-net/speedy-net/blob/staging/speedy/core/base/models.py.

Change History (3)

comment:1 by אורי, 5 years ago

Version: 2.11.11

comment:2 by Tim Graham, 5 years ago

Component: UncategorizedDatabase layer (models, ORM)
Resolution: wontfix
Status: newclosed

django-developers discussion. Aymeric suggested that these feature requests are too niche and I agree.

In the future, please limit tickets to one idea.

comment:3 by אורי, 5 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top