#30238 closed Bug (invalid)
Exception when saving model created with string for DateField
Reported by: | Mitchell Harvey | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 2.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
If you instantiate a new model object with a keyword argument value for a DateField given a string, an exception is thrown when the object is saved. However, the model is saved anyways.
Example Error:
AttributeError: 'str' object has no attribute 'isoformat'
Call Stack:
File "REDACTED", line 746, in migrate_remote_unactive_driver local_driver.save() File "REDACTED", line 171, in save super(Driver, self).save(*args, **kwargs) File "REDACTED/env/lib/python3.6/site-packages/django/db/models/base.py", line 729, in save force_update=force_update, update_fields=update_fields) File "REDACTED/env/lib/python3.6/site-packages/django/db/models/base.py", line 769, in save_base update_fields=update_fields, raw=raw, using=using, File "REDACTED/env/lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 178, in send for receiver in self._live_receivers(sender) File "REDACTED/env/lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 178, in <listcomp> for receiver in self._live_receivers(sender) File "REDACTED", line 12, in create_launch_list serialized_obj = serializers.serialize('json', [instance]) File "REDACTED/env/lib/python3.6/site-packages/django/core/serializers/__init__.py", line 128, in serialize s.serialize(queryset, **options) File "REDACTED/env/lib/python3.6/site-packages/django/core/serializers/base.py", line 89, in serialize self.handle_field(obj, field) File "REDACTED/env/lib/python3.6/site-packages/django/core/serializers/python.py", line 51, in handle_field self._current[field.name] = self._value_from_field(obj, field) File "REDACTED/env/lib/python3.6/site-packages/django/core/serializers/python.py", line 47, in _value_from_field return value if is_protected_type(value) else field.value_to_string(obj) File "REDACTED/env/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1281, in value_to_string return '' if val is None else val.isoformat() AttributeError: 'str' object has no attribute 'isoformat'
django/db/models/fields/init.py
value_to_string(self, obj)
Presumes that obj is not of type string already.
To Reproduce:
Create a model with a a field of type 'DateField'
class MyModel(models.Model): worthless_field = models.DateField(null=True, blank=True)
Instantiate and save an object of type 'MyModel' in a view.py:
my_model_args = { 'worthless_field' : '2019-02-07'} myExceptionalModel = MyModel( **my_model_args) # Exception thrown here myExceptionalModel.save() # Although, model is actually saved.
Please check if the value is a valid datetime string already before attempting to convert it to a string. It would be nice if a model was not saved when an exception is thrown.
Or do whatever you like, I have to work around it anyways.
Good luck, love Django, great job guys!
Attachments (1)
Change History (3)
by , 6 years ago
Attachment: | ticket_30238.zip added |
---|
comment:1 by , 6 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
The AttributeError
is not raised. This test fails as the assertRaisesMessage()
call:
class Tests(TestCase): def test_attribute_error_stops_save(self): my_model_args = { 'worthless_field' : '2019-02-07'} myExceptionalModel = MyModel( **my_model_args) msg = "'str' object has no attribute 'isoformat'" with self.assertRaisesMessage(AttributeError, msg): myExceptionalModel.save() self.assertEqual(0, MyModel.objects.count())
Behaviour is as expected:
>>> myExceptionalModel.save() >>> myExceptionalModel.refresh_from_db() >>> myExceptionalModel.worthless_field datetime.date(2019, 2, 7)
Sample app with model and test case attached.
comment:2 by , 6 years ago
Looking at the traceback in the ticket description, the crash comes from a signal handler, create_launch_list
.
Sample app with provided model and test case.