#29331: Model fields where the python attribute name does not match the db
column
are not saved
-------------------------------------+-------------------------------------
Reporter: Ben Mathes | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 2.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: models, | Triage Stage:
deferred_field, save | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Ben Mathes:
Old description:
> When defining a model, if you rename a model's db column, django will
> thing that model is deferred and will not {{{save()}}} it.
>
> e.g.
> {{{
> class SomeModel(models.Model):
> """
> a contrived model field where we want a "field" that is stored
> in a "field" column, but we use @property getter/setters so
> we name the SomeModel class's attribute as "_field".
> """
> name = models.TextField(null=True)
> _field = models.TextField(name="field")
>
> @property
> def field(self):
> return self._field.upper()
>
> @field.setter
> def field(self, new_value):
> self._field = new_value.lower()
> }}}
>
>
> With a renamed db column, {{{"_field"}} is in {{{self.__dict__}}}, but
> {{{"field"}}} is not,
>
> {{{
>
> def get_deferred_fields(self):
> """
> Return a set containing names of deferred fields for this instance.
> """
> return {
> f.attname for f in self._meta.concrete_fields
> if f.attname not in self.__dict__
> }
> }}}
>
> So {{{field}}} is not saved in {{{.save()}}}, because django _mistakenly_
> thinks {{{"field"}}} is deferred, so it is ignored during {{{.save()}}}
>
> {{{
> #
> https://github.com/django/django/blob/93331877c81c1c6641b163b97813268f483ede4b/django/db/models/base.py#L712
> # ...
> # elif not force_insert and deferred_fields and using ==
> self._state.db:
> # field_names = set()
> # for field in self._meta.concrete_fields:
> # if not field.primary_key and not hasattr(field, 'through'):
> # field_names.add(field.attname)
> # -> loaded_fields = field_names.difference(deferred_fields)
> # if loaded_fields:
> # update_fields = frozenset(loaded_fields)
> #
> # self.save_base(using=using, force_insert=force_insert,
> # force_update=force_update,
> update_fields=update_fields)
> # ...
> }}}
>
> Reproduced in this github django repo:
> https://github.com/benmathes/deferred_fields_bug
New description:
When defining a model, if you rename a model's db column, django will
thing that model is deferred and will not {{{save()}}} it.
e.g.
{{{
class SomeModel(models.Model):
"""
a contrived model field where we want a "field" that is stored
in a "field" column, but we use @property getter/setters so
we name the SomeModel class's attribute as "_field".
"""
name = models.TextField(null=True)
_field = models.TextField(name="field")
@property
def field(self):
return self._field.upper()
@field.setter
def field(self, new_value):
self._field = new_value.lower()
}}}
With a renamed db column, {{{"_field"}}} is in {{{self.__dict__}}}, but
{{{"field"}}} is not,
{{{
def get_deferred_fields(self):
"""
Return a set containing names of deferred fields for this instance.
"""
return {
f.attname for f in self._meta.concrete_fields
if f.attname not in self.__dict__
}
}}}
So {{{field}}} is not saved in {{{.save()}}}, because django _mistakenly_
thinks {{{"field"}}} is deferred, so it is ignored during {{{.save()}}}
{{{
#
https://github.com/django/django/blob/93331877c81c1c6641b163b97813268f483ede4b/django/db/models/base.py#L712
# ...
# elif not force_insert and deferred_fields and using ==
self._state.db:
# field_names = set()
# for field in self._meta.concrete_fields:
# if not field.primary_key and not hasattr(field, 'through'):
# field_names.add(field.attname)
# -> loaded_fields = field_names.difference(deferred_fields)
# if loaded_fields:
# update_fields = frozenset(loaded_fields)
#
# self.save_base(using=using, force_insert=force_insert,
# force_update=force_update,
update_fields=update_fields)
# ...
}}}
Reproduced in this github django repo:
https://github.com/benmathes/deferred_fields_bug
--
--
Ticket URL: <https://code.djangoproject.com/ticket/29331#comment:2>
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/067.c21883c8cc6329658967b823461fa433%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.