#python #django #django-models
#python #django #django-модели
Вопрос:
Я хочу сделать атомарное обновление объекта, тип которого может отличаться. Структура выглядит примерно так:
class MyMixin(models.Model):
size = models.BigIntegerField(null=False, default=0)
class SubClassA(MyMixin, models.Model):
<...>
class SubClassB(MyMixin, models.Model):
<...>
# obj is of type SubClassA or SubClassB
def some_func(obj):
with db.transaction.atomic():
# obj = SubClassA.objects.select_for_update().get(id=obj.id) # How do I do this?
obj.size = calculate()
obj.save()
Все примеры, которые я могу найти, явно используют <Class>.objects.select_for_update()
шаблон, но моя проблема в том, что я не знаю, каким будет класс во время выполнения. В моем коде у меня уже есть экземпляр объекта / модели, но мне нужно повторно извлечь его из базы данных, чтобы заблокировать его.
Я пытаюсь извлечь идеи из «пессимистического подхода», найденного в этом руководстве — https://medium.com/@hakibenita/how-to-manage-concurrency-in-django-models-b240fed4ee2
Должен ли я использовать очень простой метод, MyMixin
который позволяет мне устанавливать и сохранять size
? Или я мог бы явно проверить type
obj
во время выполнения и иметь кучу elif
s (чтобы сделать что-то вроде if/elif type(obj) == SubClassA: SubClassA.objects.select_for_update()...
), но это и уродливо, и не очень удобно в обслуживании.
Ответ №1:
Вы всегда можете получить класс объекта из его __class__
атрибута. Итак:
obj = obj.__class__.objects.select_for_update().get(id=obj.id)