Django - использовать часть полей модели в запросе на создание или обновление - PullRequest
6 голосов
/ 01 апреля 2020

Учитывая следующие модели в приложении Django 2.2:

class ShelfPosition(models.Model):
    shelf_code = models.CharField(max_length=10)
    row = models.IntegerField()
    column = models.IntegerField()

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=["shelf_number", "row", "column"], name="shelfpos_unique")
        ]

class Item(models.Model):
    name = models.CharField(max_length=255)
    position = models.OneToOneField(to=ShelfPosition, on_delete=models.SET_NULL, primary_key=True)

Я использую функцию поиска Django для фильтрации Item объектов в зависимости от некоторых полей ShelfPosition: Item.objects.filter(position__shelf_code="BF4")

Есть ли какой-нибудь способ, которым я мог бы реализовать подобную функциональность поиска, такую ​​как описано выше, используя get_or_create или update_or_create?

item, created = Item.objects.get_or_create(
    position__shelf_code="BF6",
    position__row=88,
    position__column=1,
    defaults={……}
)

Я считаю это менее многословным, чем следующие даже если с этим примером это не очень актуально:

item, created = Item.objects.get_or_create(
    position = Position.objects.get_or_create(
        shelf_code="BF6",
        row=88,
        column=1
    ),
    defaults={……}
)

1 Ответ

6 голосов
/ 04 апреля 2020

Не уверен, что это то, что вы ищете, но если бы вы использовали многостоловое наследование , вы могли бы получить следующее

class ShelfPosition(models.Model):
    shelf_code = models.CharField(max_length=10)
    row = models.IntegerField()
    column = models.IntegerField()

    class Meta:
        unique_together = ("shelf_code", "row", "column")

class Item(ShelfPosition):
    name = models.CharField(max_length=255)

item, created = Item.objects.get_or_create(
    shelf_code="BF6",
    row=88,
    column=1,
    defaults={
       "name": "Spam",
    }
)

Вам бы просто нужно сделать Обязательно передайте keep_parents=True при вызове item.delete(), если вы хотите сохранить строку ShelfPosition, так как поведение MTI по ​​умолчанию - удалить всю цепочку предков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...