Ticket #11527: patch-v1.diff
File patch-v1.diff, 3.6 KB (added by , 15 years ago) |
---|
-
tests/modeltests/expressions/models.py
80 80 ... 81 81 FieldError: Joined field references are not permitted in this query 82 82 83 # F expressions can be used to update attributes on single objects 84 >>> test_gmbh = Company.objects.get(name='Test GmbH') 85 >>> test_gmbh.num_employees 86 32 87 >>> test_gmbh.num_employees = F('num_employees') + 4 88 >>> test_gmbh.save() 89 >>> test_gmbh = Company.objects.get(pk=test_gmbh.pk) 90 >>> test_gmbh.num_employees 91 36 92 93 # F expressions cannot be used to update attributes which are foreign keys, or 94 # attributes which involve joins 95 >>> test_gmbh.point_of_contact = None 96 >>> test_gmbh.save() 97 >>> test_gmbh.point_of_contact is None 98 True 99 >>> test_gmbh.point_of_contact = F('ceo') 100 Traceback (most recent call last): 101 ... 102 ValueError: Cannot assign "<django.db.models.expressions.F object at ...>": "Company.point_of_contact" must be a "Employee" instance. 103 104 >>> test_gmbh.point_of_contact = test_gmbh.ceo 105 >>> test_gmbh.save() 106 >>> test_gmbh.name = F('ceo__last_name') 107 >>> test_gmbh.save() 108 Traceback (most recent call last): 109 ... 110 FieldError: Joined field references are not permitted in this query 111 112 # F expressions cannot be used to update attributes on objects which do not yet 113 # exist in the database 114 >>> acme = Company(name='The Acme Widget Co.', num_employees=12, num_chairs=5, 115 ... ceo=test_gmbh.ceo) 116 >>> acme.num_employees = F('num_employees') + 16 117 >>> acme.save() 118 Traceback (most recent call last): 119 ... 120 TypeError: int() argument must be a string or a number, not 'ExpressionNode' 83 121 """} -
docs/ref/models/instances.txt
104 104 Explicitly specifying auto-primary-key values is mostly useful for bulk-saving 105 105 objects, when you're confident you won't have primary-key collision. 106 106 107 Updating attributes using ``F()`` expressions 108 --------------------------------------------- 109 110 Sometimes you'll need to perform a simple arithmetic task on a field: incrementing, decrementing, multiplying or dividing. Usually in Python you would do something like this:: 111 112 >>> product = Product.objects.get(name='Venezuelan Beaver Cheese') 113 >>> product.number_sold += 1 114 >>> product.save() 115 116 However, this pattern leaves your code open to `race conditions <http://en.wikipedia.org/wiki/Race_condition#Computing>`_, which occur when two processes or threads try to update the same object at the same time. In order to avoid, this, you can use :ref:`F() expressions <query-expressions>` to place the burden of synchronization on the database, which will typically be much better at avoiding these issues due to its ACID-compliant architecture. 117 118 Using ``F()`` expressions, the above code would instead be:: 119 120 >>> from django.db.models import F 121 >>> product = Product.objects.get(name='Venezuelan Beaver Cheese') 122 >>> product.number_sold = F('number_sold') + 1 123 >>> product.save() 124 125 After saving, it is necessary to reload the object in question in order to access the actual value of the updated field. This can be done quite simply:: 126 127 >>> product = Products.objects.get(pk=product.pk) 128 129 ``F()`` expressions work only on numeric fields (such as integers and floats), and support the standard Python operators for addition, subtraction, multiplication and division. 130 107 131 What happens when you save? 108 132 --------------------------- 109 133