﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
29331	Model fields where the field name is shadowed by Python property aren't saved	Ben Mathes	nobody	"Reproduced in this github django repo: https://github.com/benmathes/deferred_fields_bug


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"	Bug	closed	Database layer (models, ORM)	2.0	Normal	invalid	models, deferred_field, save		Accepted	0	0	0	0	0	0
