select and update database record with a single queryset

select and update database record with a single queryset

How do I run an update and select statements on the same queryset rather than having to do two queries: 
- one to select the object
- and one to update the object
The equivalent in SQL would be something like:
update my_table set field_1 = 'some value' where pk_field = some_value

Solutions/Answers:

Answer 1:

Use the queryset object update method:

MyModel.objects.filter(pk=some_value).update(field1='some value')

Answer 2:

Django database objects use the same save() method for creating and changing objects.

obj = Product.objects.get(pk=pk)
obj.name = "some_new_value"
obj.save()

How Django knows to UPDATE vs. INSERT
If the object’s primary key attribute is set to a value that evaluates to True (i.e., a value
other than None or the empty string), Django executes an UPDATE. If
the object’s primary key attribute is not set or if the UPDATE didn’t
update anything, Django executes an INSERT.

Ref.: https://docs.djangoproject.com/en/1.9/ref/models/instances/

Answer 3:

This answer compares the above two approaches.
If you want to update many objects in a single line, go for:

# Approach 1
MyModel.objects.filter(field1='Computer').update(field2='cool')

Otherwise you would have to iterate over the query set and update individual objects:

#Approach 2    
objects = MyModel.objects.filter(field1='Computer')
for obj in objects:
    obj.field2 = 'cool'
    obj.save()
  1. Approach 1 is faster because, it makes only one database query, compared to approach 2 which makes ‘n+1’ database queries. (For n items in the query set)

  2. Fist approach makes one db query ie UPDATE, the second one makes two: SELECT and then UPDATE.

  3. The tradeoff is that, suppose you have any triggers, like updating updated_on or any such related fields, it will not be triggered on direct update ie approach 1.

  4. Approach 1 is used on a queryset, so it is possible to update multiple objects at once, not in the case of approach 2.

Answer 4:

only in a case in serializer things, you can update in very simple way!

my_model_serializer = MyModelSerializer(
    instance=my_model, data=validated_data)
if my_model_serializer.is_valid():

    my_model_serializer.save()

only in a case in form things!

instance = get_object_or_404(MyModel, id=id)
form = MyForm(request.POST or None, instance=instance)
if form.is_valid():
    form.save()

References