2016-04-01 16 views
0

私は値を返すDjango Rest APIを持っています。
このAPIは同時にヒットする可能性があります/
django rest APIはスレッドセーフですか? views.pyDjango Rest Frameworkスレッドは安全ですか?

class ApiDetail(generics.RetrieveUpdateDestroyAPIView): 
    queryset = Api.objects.all() 
    serializer_class = ApiSerializer 

    def get(self, request, *args, **kwargs): 
     currentForm = self.kwargs['pk'] 
     currentApi = Api.objects.get(pk = currentItem) 
     currentApi.currentNumber += 1 

     tempCurrentNum = currentApi.currentNumber 
     strCurrentNum = str(tempCurrentNum) 
     currentNumLength = len(strCurrentNum) 

     if(currentNumLength > currentApi.maxNumberOfDigitsInNum): 
      currentApi.currentNumber = 1 

     currentApi.iterativeField = currentApi.fieldPrefix + str(currentApi.currentNumber) 
     currentApi.save() 
     return self.retrieve(request, *args, **kwargs) 


$http.get('//0.0.0.0:8000/api/tempName?format=json') 
     .success(function (data) { 
       $scope.iterativeNum = data.iterativeField 
     }) 

私は2つの別々の呼び出しは「ApiDetail」ビューをヒットし、前と同じ番号を返すことができます心配です。

私はPython/Djangoを使ってMacで作業しています。 Django 1.9.4、Django Rest 3.3.3。

答えて

0

ここでの問題は、django-rest-frameworkよりもコードのほうが多いと思います。あなたが使用したいのはF()の式です。https://docs.djangoproject.com/en/1.9/ref/models/expressions/#f-expressions

具体的には、「F()を使用した競合状態の回避」を参照してください。あなたはの線に沿って何かになってしまいます

:限りmaxNumberofDigitsとして

from django.db.models import F 
from rest_framework import generics 


class ApiDetail(generics.RetrieveUpdateDestroyAPIView): 
    queryset = Api.objects.all() 
    serializer_class = ApiSerializer 

    def get(self, request, *args, **kwargs): 
     currentApi = self.get_object() 
     currentApi.currentNumber = F('currentNumber') + 1 
     currentApi.iterativeField = F('fieldPrefix') + (F('currentNumber') + 1) 
     currentApi.save() 
     return super(ApiDetail, self).get(request, *args, **kwargs) 

、私は読者の練習として残しておきます。しかし、私は個人的には、最大桁数ではなく、絶対数maxを行うことをお勧めします。 Case()/When()F()を使って簡単に上記を達成できます。 (たとえば、最大6桁、最大数は999999になります)。

+0

Fにすべてをラップすることができ()非常に興味深いですが、それはまだ私の問題は解決しません。私はロジックを実行するビューにデータベース内の項目を読み込む必要があります。それだけで私はそれを保存することができます。私はデータベース内のデータを変更することはできません。 –

0

あなたがtransaction with transaction.atomic()

def get(self, request, *args, **kwargs): 
    with transaction.atomic() 
     currentApi = Api.objects.get(pk=currentItem) 
     ... 
     currentApi.save() 

    return self.retrieve(request, *args, **kwargs) 
関連する問題