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
# %% About
# - Name: Database ORM Create
# - Difficulty: easy
# - Lines: 3
# - Minutes: 2

# %% 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

# %% 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()`

# %% Doctests
"""
>>> 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()
"""

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

# %% Imports
import os; os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django; django.setup()
from shop.models import Customer

# %% Types
result: Customer

# %% Data
Customer.objects.create(firstname='John', lastname='Doe')

# %% Result
result = ...

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

# %% 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

# %% 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:
#    Zaktualizuj `Customer` firstname: John, lastname: Doe
#    Ustaw firstname: Jane
# 2. Użyj metody `.update()`

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

# %% Doctests
"""
>>> 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()
"""

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

# %% Imports
import os; os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django; django.setup()
from shop.models import Customer

# %% Types
result: int

# %% Data
Customer.objects.create(firstname='John', lastname='Doe')

# %% Result
result = ...

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

# %% 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

# %% 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()`

# %% Doctests
"""
>>> 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()
"""

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

# %% Imports
import os; os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django; django.setup()
from shop.models import Customer

# %% Types
result: Customer

# %% Data
Customer.objects.create(firstname='John', lastname='Doe')

# %% Result
result = ...