#30080: New optional settings - disable bulk_create in all managers and call
self.full_clean() before saving the models
-------------------------------------+-------------------------------------
Reporter: אורי | Owner: nobody
Type: New feature | Status: closed
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by אורי:
Old description:
> We are using Django for [https://github.com/speedy-net/speedy-net 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:
>
> {{{#!python
> 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/uri_merge_with_master_2019-01-05_a/speedy/core/base/models.py.
New description:
We are using Django for [https://github.com/speedy-net/speedy-net 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:
{{{#!python
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.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/30080#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/069.bcfcc10e2f7e8f9db6ca64b3e966a3d3%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.