Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/tutorial/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,21 @@ user = UserModel.objects.create(username="hakancelik")
It is the same as save, but it returns the user.


### Get or Create

Get or create method tries to get an existing record from the database.
If the record does not exist, it creates a new one.
It returns a tuple of `(instance, created)` where `created` is a boolean indicating whether the record was created.

```python
user, created = UserModel.objects.get_or_create(username="hakancelik")

if created:
print("New user created")
else:
print("Existing user found")
```

### All

All method is used to get all data from the database and iterate model instances.
Expand Down
6 changes: 6 additions & 0 deletions src/pydbm/database/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ def create(self, **kwargs) -> DbmModel:

return model

def get_or_create(self, **kwargs) -> tuple[DbmModel, bool]:
try:
return self.get(**kwargs), False
except self.model.DoesNotExists:
return self.create(**kwargs), True

def get(self, *, id: str | None = None, **unique_together) -> DbmModel:
if id is None:
if self.model._config.unique_together != tuple(unique_together.keys()):
Expand Down
44 changes: 44 additions & 0 deletions tests/models/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,47 @@ class Model(DbmModel):
last = Model.objects.last()
assert last is not None
assert last.username in ("hakan", "celik")


def test_base_get_or_create_creates(teardown_db):
class Model(DbmModel):
username: str

class Config:
unique_together = ("username",)

instance, created = Model.objects.get_or_create(username="hakan")
assert created is True
assert instance.username == "hakan"
assert Model.objects.count() == 1


def test_base_get_or_create_gets(teardown_db):
class Model(DbmModel):
username: str

class Config:
unique_together = ("username",)

Model.objects.create(username="hakan")
instance, created = Model.objects.get_or_create(username="hakan")
assert created is False
assert instance.username == "hakan"
assert Model.objects.count() == 1


def test_base_get_or_create_multiple_fields(teardown_db):
class Model(DbmModel):
name: str
surname: str

class Config:
unique_together = ("name", "surname")

instance, created = Model.objects.get_or_create(name="hakan", surname="celik")
assert created is True

instance2, created2 = Model.objects.get_or_create(name="hakan", surname="celik")
assert created2 is False
assert instance.id == instance2.id
assert Model.objects.count() == 1