2016-07-10 3 views
1
# /uri/one/{pk}/ 
class ModelOneView(generic.View): 
    def post(self, request, pk): # pk has the same value as below 
     Model.objects.filter(pk=pk).update(name=request.POST['name']) 
     return HttpResponse(status=200) 

# /uri/two/{pk}/ 
class ModelTwoView(generic.View): 
    def post(self, request, pk): # pk has the same value as above 
     Model.objects.filter(pk=pk).update(bool_field=True) 
     return HttpResponse(status=200) 

Я упростил свой код немного, но в основном то, что я делаю, что у меня есть два разных URI, что и некоторые изменения на той же самой модели (не то же самое поле, хотя). Проблема в том, что мой клиент вызывает их в основном в одно и то же время.Джанго Редактирование модели одновременно

// script.js in my index.html 
function notHealthyForDjango() { 
    callFirstURI(); 
    callSecondURI(); 
} 

Ни Django, ни Client не бросают какие-либо ошибки в какой-либо момент, я получаю ответы OK. Однако изменения, которые я пытаюсь сделать с вызовомFirstURI(); никогда не попадайте в базу данных. Но когда я прокомментирую callSecondURI();

function notHealthyForDjango() { 
    callFirstURI(); 
    //callSecondURI(); 
} 

Теперь звонок в первый URI работает по назначению!

Как я могу решить эту проблему? Я использую psql, Python 2.7 и Django 1.9. Как изменить поля моих моделей без риска таких столкновений?

EDIT

Я хотел бы найти на стороне сервера решение проблемы, а не только временные JavaScript запросы моего клиента более благоприятно.

+0

Вы попробовали мое предложение? – e4c5

+0

Прости, что у меня еще не было времени. Я вернусь к этому позже на этой неделе и посмотрю, разрешит ли это проблему. Это кажется очень многообещающим, и я очень ценю вашу помощь! Я прошу прощения за задержку. – user3622167

+0

Рад, что это сработало. Невозможно повысить свой вопрос сегодня (из голосов, сделайте завтра) – e4c5

ответ

1

Считаете ли вы, что select_for_update?

Возвращает QuerySet, который будет блокировать строки до конца сделки, генерируя SELECT ... FOR UPDATE заявление SQL на поддерживаемых баз данных.

Поддерживаемые базы данных - Postgresql, Oracle и Mysql. Я заметил, что вы не указали свою базу данных. Хотя sqlite не поддерживается, проблема редко возникает, по крайней мере, в Linux, потому что блокировка файлов гарантирует, что одни и те же данные не будут обработаны с помощью sqlite.

Для достижения наилучших результатов вам потребуется использовать атомную транзакцию.

def post(self, request, pk): # pk has the same value as below 
    with transaction.atomic(): 
     Model.objects.select_for_update().filter(pk=pk).update(
         name=request.POST['name']) 
     return HttpResponse(status=200) 
0

два предложения, которые вы можете попробовать:

  1. Запуск callSecondURI() после завершения callFirstURI() с помощью обратного вызова в запросе AJAX

  2. Это может не относиться (я ни в коем случае не является экспертом по это), но это звучит так, как будто это может быть связано с многопоточным. Посмотрите на this question для декоратора, который имеет дело с этим.

+0

Эй, Джейкоб! Благодарю за ваш ответ. Выполнение этого, как вы пишете в своей первой рекомендации, хорошо работает. Однако, если это возможно, я бы хотел найти решение на стороне сервера для этой проблемы. Мне плохо, что я не понимаю. Я проведу вторую рекомендацию чуть позже! – user3622167

+0

Привет, рад, что помог.Если решение работает, то, пожалуйста, подумайте о принятии ответа, хотя я понимаю, что не предлагал подход на стороне сервера –

Смежные вопросы