Эффективно обновить несколько полей в Django - PullRequest
1 голос
/ 13 апреля 2020

Django новичок здесь. У меня есть модель «многие ко многим», и я хочу обновить несколько значений одновременно.

Это модель (упрощенная):

class Inventory(models.Model):
    item = models.ForeignKey(Items, models.CASCADE)
    player = models.ForeignKey(Players, models.CASCADE)
    count = models.PositiveIntegerField()

Сейчас я делаю следующее:

for key in dict:
    change_value = Inventory.objects.get(player=player, item=key)
    change_value.count += dict[key]
    change_value.save()

По крайней мере, в моей тестовой среде HDD это очень медленно. Есть ли более эффективный способ сделать это? В других сообщениях было предложено использовать обновление вместо этого, так что это будет:

for key in dict:
    Inventory.objects.get(player=player, item=key).update(count=dict[key])

Это будет быстрее? Можно ли еще улучшить это, обновляя несколько записей одновременно? Кроме того, существует ли эффективный способ добавления нескольких новых записей?

1 Ответ

1 голос
/ 13 апреля 2020

Лучше использовать .filter(..) сверх .get(..), поскольку тогда количество запросов равно половине, поэтому:

for k, v in data.items():
    Inventory.objects.filter(player=player, item=k).update(count=v)

В качестве альтернативы вы можете даже выполнить сопоставление в одном запросе с помощью:

from django.db.models import Case, PositiveIntegerField, Value, When

Inventory.objects.filter(player=player, item__in=data).update(
    count=Case(
        *[When(item=k, then=Value(v)) for k, v in data.items()]
        output_field=PositiveIntegerField()
    )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...