6.4. ORM Update

  • .update()

  • .save()

  • .update_or_create()

  • .bulk_update()

  • .select_for_update()

6.4.1. Update

  • QuerySet.update()

>>> Customer.objects.filter(firstname='Mark', lastname='Watney').update(is_verified=True)

6.4.2. Save

  • Model.save()

>>> mark = Customer.objects.get(firstname='Mark', lastname='Watney')
>>> mark.is_verified = True
>>> mark.save()

6.4.3. Update or Create

  • QuerySet.update_or_create()

>>> customers = [
...     ('Mark', 'Watney'),
...     ('Melissa', 'Lewis'),
...     ('Rick', 'Martinez'),
...     ('Alex', 'Vogel'),
...     ('Beth', 'Johansson'),
...     ('Chris', 'Beck'),
... ]
>>>
>>> for firstname, lastname in customers:
...     customer, was_created = Customer.objects.update_or_create(
...         firstname=firstname,
...         lastname=lastname,
...         defaults={'is_verified': True},
...     )
...     if was_created:
...         print(f'Created: {customer}')
...     else:
...         print(f'Updated: {customer}')

In the above example, we have a list of users that we want to add to the database. We use the update_or_create method to add them. If the user already exists, we update the is_verified field to True.

6.4.4. Bulk Update

  • QuerySet.bulk_update()

>>> customers = [
...     Customer.objects.create(firstname='Mark', lastname='Watney'),
...     Customer.objects.create(firstname='Melissa', lastname='Lewis'),
... ]
>>>
>>> customers[0].is_verified = True
>>> customers[1].is_verified = False
>>>
>>> Customer.objects.bulk_update(customers, ['is_verified'])
2

6.4.5. Select for Update

  • QuerySet.select_for_update()

Returns a queryset that will lock rows until the end of the transaction, generating a SELECT ... FOR UPDATE SQL statement on supported databases.

>>> from django.db import transaction
>>>
>>> customers = Customer.objects.select_for_update().filter(gender='male')
>>>
>>> with transaction.atomic():
...     for customer in customers:
...         ...

6.4.6. Assignments

# doctest: +SKIP_FILE
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Database ORM Create
# - Difficulty: easy
# - Lines: 3
# - Minutes: 2

# %% English
# 0. Use `myproject.shop`
# 1. Using ORM get user:
#    firstname: John, lastname: Doe
# 2. Update his firstname to Jane
# 3. Use `.save()` method

# %% Polish
# 0. Użyj `myproject.shop`
# 1. Używając ORM znajdź użytkownika:
#    firstname: John, lastname: Doe
# 2. Zmień jego imię na Jane
# 3. Użyj metody `.save()`

# %% Hints
# - `.get()`
# - `.save()`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 10), \
'Python 3.10+ required'

>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'

>>> john = Customer.objects.filter(firstname='John', lastname='Doe')
>>> jane = Customer.objects.filter(firstname='Jane', lastname='Doe')

>>> assert not john.exists()
>>> assert jane.exists()

>>> assert jane.delete()
>>> assert john.delete()
"""

# Required for Django to work
import os; os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django; django.setup()

from shop.models import Customer
Customer.objects.create(firstname='John', lastname='Doe')

...

# Using ORM get user:
# firstname: John, lastname: Doe
# Update his firstname to Jane
# Use `.save()` method
# type: tuple[int, dict[str,int]]
...


# doctest: +SKIP_FILE
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Database ORM Create
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 0. Use `myproject.shop`
# 1. Define variable `result` with result of ORM call for:
#    Update `Customer` firstname: John, lastname: Doe
#    Set firstname: Jane
# 2. Use `.update()` method

# %% Polish
# 0. Użyj `myproject.shop`
# 1. Zdefiniuj zmienną `result` z wynikiem zapytania ORM dla:
#    Zaktulizuj `Customer` firstname: John, lastname: Doe
#    Ustaw firstname: Jane
# 2. Użyj metody `.update()`

# %% Hints
# - `.filter()`
# - `.update()`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 10), \
'Python 3.10+ required'

>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is int, \
'Variable `result` has invalid type, should be int'

>>> result
1

>>> john = Customer.objects.filter(firstname='John', lastname='Doe')
>>> jane = Customer.objects.filter(firstname='Jane', lastname='Doe')

>>> assert not john.exists()
>>> assert jane.exists()

>>> assert jane.delete()
>>> assert john.delete()
"""

# Required for Django to work
import os; os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django; django.setup()

from shop.models import Customer
Customer.objects.create(firstname='John', lastname='Doe')


...

# Define variable `result` with result of ORM call for:
# Update `Customer` firstname: John, lastname: Doe
# Set firstname: Jane
# type: tuple[int, dict[str,int]]
result = ...


# doctest: +SKIP_FILE
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Database ORM Create
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 0. Use `myproject.shop`
# 1. Define variable `result` with result of ORM call for:
#    update or create `Customer`
#    firstname: John, lastname: Doe
# 2. Use `.update_or_create()` method
# 3. Mind, that method returns a two element tuple
#    but we need only a `Customer`

# %% Polish
# 0. Użyj `myproject.shop`
# 1. Zdefiniuj zmienną `result` z wynikiem zapytania ORM dla:
#    zaktualizuj lub stwórz `Customer`
#    firstname: John, lastname: Doe
# 2. Użyj metody `.update_or_create()`
# 3. Zwróć uwagę, że metoda zwraca dwu elementową tuplę
#    a potrzebny jest tylko `Customer`

# %% Hints
# - `.update_or_create()`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 10), \
'Python 3.10+ required'

>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is Customer, \
'Variable `result` has invalid type, should be Customer'

>>> result
<Customer: John Doe>

>>> john = Customer.objects.filter(firstname='John', lastname='Doe')
>>> assert john.exists()
>>> assert john.delete()
"""

# Required for Django to work
import os; os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django; django.setup()

from shop.models import Customer
Customer.objects.create(firstname='John', lastname='Doe')

...

# Define variable `result` with result of ORM call for:
# update or create `Customer`
# firstname: John, lastname: Doe
# Use `.update_or_create()` method
# Mind, that method returns a two element tuple
# but we need only a `Customer`
# type: Customer
result = ...