Code

Ticket #4102: only_fields_django-1.4.patch

File only_fields_django-1.4.patch, 4.5 KB (added by niwi, 2 years ago)
  • docs/ref/models/instances.txt

     
    135135 
    136136To save an object back to the database, call ``save()``: 
    137137 
    138 .. method:: Model.save([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS]) 
     138.. method:: Model.save([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, only_fields=None]) 
    139139 
    140140.. versionadded:: 1.2 
    141141   The ``using`` argument was added. 
     
    334334<query-expressions>` and their :ref:`use in update queries 
    335335<topics-db-queries-update>`. 
    336336 
     337Specifying which fields to save 
     338------------------------------- 
     339 
     340If ``save()`` is passed a list of field names as keyword argument ``only_fields``,  
     341only the fields named in that list will be saved to the database. This may be  
     342desirable if you want to update just one or a few fields on an object, as there  
     343will be a slight performance benefit from preventing all of the model fields  
     344from being updated in the database. For example: 
     345 
     346    product.name = 'Name changed again' 
     347    product.save(only_fields=['name']) 
     348 
     349 
    337350Deleting objects 
    338351================ 
    339352 
  • django/db/models/base.py

     
    449449            return getattr(self, field_name) 
    450450        return getattr(self, field.attname) 
    451451 
    452     def save(self, force_insert=False, force_update=False, using=None): 
     452    def save(self, force_insert=False, force_update=False, using=None, only_fields=None): 
    453453        """ 
    454454        Saves the current instance. Override this in a subclass if you want to 
    455455        control the saving process. 
     
    460460        """ 
    461461        if force_insert and force_update: 
    462462            raise ValueError("Cannot force both insert and updating in model saving.") 
    463         self.save_base(using=using, force_insert=force_insert, force_update=force_update) 
     463        self.save_base(using=using, force_insert=force_insert,  
     464                        force_update=force_update, only_fields=only_fields) 
    464465 
    465466    save.alters_data = True 
    466467 
    467468    def save_base(self, raw=False, cls=None, origin=None, force_insert=False, 
    468             force_update=False, using=None): 
     469            force_update=False, using=None, only_fields=None): 
    469470        """ 
    470471        Does the heavy-lifting involved in saving. Subclasses shouldn't need to 
    471472        override this method. It's separate from save() in order to hide the 
     
    513514        if not meta.proxy: 
    514515            non_pks = [f for f in meta.local_fields if not f.primary_key] 
    515516 
     517            if only_fields:  
     518                non_pks = [f for f in non_pks if f.name in only_fields]  
     519 
    516520            # First, try an UPDATE. If that doesn't update anything, do an INSERT. 
    517521            pk_val = self._get_pk_val(meta) 
    518522            pk_set = pk_val is not None 
  • tests/modeltests/update_only_fields/__init__.py

     
     1# -*- coding: utf-8 -*- 
     2 
     3 
  • tests/modeltests/update_only_fields/tests.py

     
     1from __future__ import absolute_import 
     2 
     3from django.test import TestCase 
     4from .models import Person 
     5 
     6class UpdateOnlyFieldsTests(TestCase): 
     7    def test_only_update(self): 
     8        s = Person.objects.create(name='Sara', gender='F') 
     9        self.assertEqual(s.gender, 'F') 
     10 
     11        s.gender = 'M' 
     12        s.save(only_fields=['name']) 
     13 
     14        s = Person.objects.get(pk=s.pk) 
     15        self.assertEqual(s.gender, 'F') 
  • tests/modeltests/update_only_fields/models.py

     
     1 
     2from django.db import models 
     3 
     4GENDER_CHOICES = ( 
     5    ('M', 'Male'), 
     6    ('F', 'Female'), 
     7) 
     8 
     9class Person(models.Model): 
     10    name = models.CharField(max_length=20) 
     11    gender = models.CharField(max_length=1, choices=GENDER_CHOICES) 
     12 
     13    def __unicode__(self): 
     14        return self.name