No validation with Django >= 3.2.x
MiltosD opened this issue · 1 comments
One line description of the issue
Since Django 3.2.1 a check has been added to prevent instantiation of an abstract model. This seems to have broken the validation of a model instance with an EmbeddedField
django/db/models/base.py
# django/db/models/base.py
class Model(metaclass=ModelBase):
def __init__(self, *args, **kwargs):
# Alias some things as locals to avoid repeat global lookups
cls = self.__class__
opts = self._meta
_setattr = setattr
_DEFERRED = DEFERRED
if opts.abstract:
raise TypeError('Abstract models cannot be instantiated.')
Example
from django.core.validators import URLValidator
from djongo import models
class Address(models.Model):
city = models.CharField(max_length=50)
homepage = models.URLField(validators=[URLValidator])
class Meta:
abstract=True
class Entry(models.Model):
_id = models.ObjectIdField()
address = models.EmbeddedField(model_container=Address)
from entities.models import Entry
e = Entry(address={'city': 'New York', 'homepage': 'http://mypage.com'})
e.clean_fields()
Traceback
Traceback (most recent call last):
File "/usr/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "", line 1, in
File "site-packages/django/db/models/base.py", line 1497, in clean_fields
setattr(self, f.attname, f.clean(raw_value, self))
File "site-packages/django/db/models/fields/init.py", line 754, in clean
value = self.to_python(value)
File "site-packages/djongo/models/fields.py", line 261, in to_python
value = self._value_thru_container(value)
File "site-packages/djongo/models/fields.py", line 182, in _value_thru_container
inst = self.model_container(**value)
File "site-packages/django/db/models/base.py", line 465, in init
raise TypeError("Abstract models cannot be instantiated.")
TypeError: Abstract models cannot be instantiated.
I managed to instantiate by declaring the model as managed = False
in the Meta class and leaving abstract
to False
. What this does, is that it actually creates a migration operation for the model but does not create the collection, which, effectively is the same behavior as setting abstract = True
. However, according to the Django docs, the purpose of managed = False
is different, so I'm seeing this as a temporary solution...