#28019: Django django.db.models.Model.save() logic bit illogical?
-------------------------------------+-------------------------------------
               Reporter:  Jacek      |          Owner:  nobody
  Kałucki                            |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  1.10
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 In code below, calling “Foo(name='Foo Bar').save()” method raises
 ValueError “Cannot force an update in save() with no primary key” - let’s
 check what goes wrong here:
 1) I didn’t pass any parameters so why logic mentions about “force” and
 “update” since I’m not forcing nor updating but inserting new data row?
 I’ve figured out that logic adds fields to “update_fields” parameters
 itself and in this case it’s a “name” which is class Foo property name.
 It won’t happened if there is no class inheritance scenario. Why? But it
 leads us to the next point.
 2) Let’s check when the “not pk_set and (force_update or update_fields)”
 condition is fulfilled.
 IMHO if “pk_set” is false there is no need to check “update_fields”
 because it’s never used in this scenario, it may be used only in case of
 “pk_set” equals true but these states are mutually exclusive.

 My proposal is to revise “get_deferred_fields()” method to handle class
 attributes correctly in case of inheritance and remove redundant
 “update_fields” checking on inserts.

 {{{
 #!div style="font-size: 80%"
 Code highlighting:
   {{{#!python
 class Bar(models.Model):

     name = models.CharField(max_length=100, blank=True)


 class Foo(Bar):

     first_name = models.CharField(max_length=50, blank=True)
     last_name = models.CharField(max_length=50, blank=True)

     def __init__(self, *args, **kwargs):
         name = kwargs.get('name')
         if name:
             (first_name, last_name) = name.split()
             kwargs['first_name'] = first_name
             kwargs['last_name'] = last_name
         super(Foo, self).__init__(*args, **kwargs)

     @property
     def name(self):
         names = (self.first_name, self.last_name)
         return " ".join(x for x in names if x)

     @name.setter
     def name(self, value):
         (self.first_name, self.last_name) = value.split()
   }}}
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28019>
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/052.c3615cad4c138a656c0af8a4222847ca%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to