Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit edcabe0

Browse files
authored
get_or_create method (#106)
1 parent a33ea36 commit edcabe0

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

docs/making_queries.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ await Note.objects.order_by("id").limit(1).offset(1).all()
140140
await Note.objects.filter(text__icontains="mum").limit(2).all()
141141
```
142142

143+
#### .exists()
144+
145+
To check if any instances matching the query exist. Returns `True` or `False`.
146+
147+
```python
148+
await Note.objects.filter(completed=True).exists()
149+
```
150+
143151
### Updating instances
144152

145153
`.update()` method is defined on model instances.
@@ -169,3 +177,16 @@ Then delete the instance:
169177
```python
170178
await note.delete()
171179
```
180+
181+
### Convenience methods
182+
183+
#### get_or_create()
184+
185+
To get an existing instance matching the query, or create a new one.
186+
This will retuurn a tuple of `instance` and `created`.
187+
188+
```python
189+
note, created = await Note.objects.get_or_create(text="Going to car wash")
190+
```
191+
192+
**Note**: Since this is doing a [get()](#get), it can raise `MultipleMatches` exception.

orm/models.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,14 @@ async def create(self, **kwargs):
305305
instance.pk = await self.database.execute(expr)
306306
return instance
307307

308+
async def get_or_create(self, **kwargs) -> typing.Tuple[typing.Any, bool]:
309+
try:
310+
instance = await self.get(**kwargs)
311+
return instance, False
312+
except NoMatch:
313+
instance = await self.create(**kwargs)
314+
return instance, True
315+
308316
def _prepare_order_by(self, order_by: str):
309317
reverse = order_by.startswith("-")
310318
order_by = order_by.lstrip("-")

tests/test_models.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,14 @@ async def test_model_first():
246246
assert await User.objects.first(name="Jane") == jane
247247
assert await User.objects.filter(name="Jane").first() == jane
248248
assert await User.objects.filter(name="Lucy").first() is None
249+
250+
251+
async def test_model_get_or_create():
252+
async with database:
253+
user, created = await User.objects.get_or_create(name="Tom")
254+
255+
assert created is True
256+
assert await User.objects.get(pk=user.id) == user
257+
258+
user, created = await User.objects.get_or_create(name="Tom")
259+
assert created is False

0 commit comments

Comments
 (0)