Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select a record and update it, with a single queryset in Django?

People also ask

How do I update a specific field in Django?

Use update_fields in save() If you would like to explicitly mention only those columns that you want to be updated, you can do so using the update_fields parameter while calling the save() method. You can also choose to update multiple columns by passing more field names in the update_fields list.

Can I filter a Queryset Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.

How do I get latest record in Django ORM?

Django Doc: latest(field_name=None) returns the latest object in the table, by date, using the field_name provided as the date field. This is the neat way to do it. Also, "If your model's Meta specifies get_latest_by, you can leave off the field_name argument to latest()" as per the docs.

How do I append Queryset in Django?

Use union operator for queryset | to take union of two queryset. If both queryset belongs to same model / single model than it is possible to combine querysets by using union operator. One other way to achieve combine operation between two queryset is to use itertools chain function.


Use the queryset object update method:

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

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/


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.


1st method

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

2nd Method

q = MyModel.objects.get(pk=some_value)
q.field1 = 'some value'
q.save()

3rd method

By using get_object_or_404

q = get_object_or_404(MyModel,pk=some_value)
q.field1 = 'some value'
q.save()

4th Method

if you required if pk=some_value exist then update it other wise create new one by using update_or_create.

MyModel.objects.update_or_create(pk=some_value,defaults={'field1':'some value'})

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()

If you need to set the new value based on the old field value that is do something like:

update my_table set field_1 = field_1 + 1 where pk_field = some_value

use query expressions:

MyModel.objects.filter(pk=some_value).update(field1=F('field1') + 1)

This will execute update atomically that is using one update request to the database without reading it first.