Параллелизм в админке django - PullRequest
2 голосов
/ 25 июня 2010

Моя модель:

class Order(models.Model):
    property_a = models.CharField()
    property_b = models.CharField()
    property_c = models.CharField()

Многие пользователи будут получать доступ к данной записи в течение короткого периода времени через страницу смены администратора, поэтому у меня возникают проблемы с параллелизмом:

Пользователь 1 и 2 открывают страницу изменений одновременно. Предположим, что все значения являются пустыми, когда они загружают страницу. Пользователь 1 устанавливает property_a в «a», а property_b в «b», затем сохраняет. Через секунду, если пользователь 2 изменяет свойство b, а затем сохраняет, он спокойно перезапишет все значения пользователя 1. в этом случае property_a вернется к пустому состоянию, а b и c будут теми, которые вставил пользователь 2.

Мне нужны рекомендации, как с этим справиться. Если у меня должно быть поле версии в модели, как мне передать его администратору, где я делаю проверку, чтобы я мог элегантно уведомить пользователя, что его изменения не могут быть сохранены, потому что другой пользователь изменил запись? Есть ли более простой способ, чем просто вернуть ошибку пользователю?

1 Ответ

0 голосов
/ 25 июня 2010

Стандартное решение - запретить пользователям делиться одной записью. Не совсем понятно, почему так много пользователей возятся с одним и тем же экземпляром Order.

Учтите, что Order, вероятно, составной объект, и вы слишком много вложили в одну модель. Это первое и лучшее решение.

Если (по необъяснимым причинам) вы не разложите это, то вам придется создать транзакцию обновления из двух частей.

  1. Запрос данных. Сравните с исходным запросом, выполненным для сеанса этого пользователя.

  2. Если данные не соответствуют исходному запросу, кто-то другой изменил их. Изменения пользователя отменяются, откатываются, стираются, и пользователь видит новый запрос.

  3. Если данные совпадают, вы можете попытаться зафиксировать изменение.

Приведенный выше алгоритм имеет условие состязания, которое обычно разрешается с помощью низкоуровневого SQL. Обратите внимание, что это делает работу пользователя недействительной, что делает его максимально раздражающим.

Вот почему ваш первый выбор - декомпозировать ваши модели, чтобы исключить параллелизм.


в моей модели есть поле "Разные заметки"

Это плохой дизайн. (а) Параллелизм разрушен столкновениями на этом поле. (б) Там нет журнала или истории комментариев.

Пункт (b) означает, что плохо ведущий себя пользователь может злонамеренно испортить эти данные. Если вы сохраняете заметки и комментарии в виде журнала, вы можете - в принципе - ограничивать пользователей только изменением их собственных комментариев.

[В большинстве баз данных с «различными примечаниями» поле стало дорогостоящим, трудно поддерживаемым, полным важных, но не поддающихся анализу данных. В разных заметках пользователи изобретают свои собственные процессы вне прикладного программного обеспечения. ]

«Разные заметки» должны рассматриваться как журнал, с неограниченным количеством заметок - с отметкой даты - идентифицируемых пользователем - добавляется к Заказу

Если вы просто разбиваете проект, чтобы поместить заметки в отдельную таблицу, вы решаете проблемы параллелизма.

...