0

djangoとdjango restフレームワークを使用して音楽webappを作成しようとしています。問題はlistenレコードカウンターの実装にあります。そのsong_idでは、user_idが増加するはずです。私のモデルは、このようになりますDjangoスーパーキーが存在しない場合は行を作成し、それ以外の場合は

class Listen_Record(models.Model): 
    number=None 
    listen_count = models.IntegerField(default=1,null=True) 
    user = models.ForeignKey(User) 
    songid = models.ForeignKey(Song) 

私の見解、

class ListenRecordCreateAPIView(GenericAPIView,CreateModelMixin,UpdateModelMixin): 
    queryset = Listen_Record.objects.all() 
    serializer_class = ListenRecordListSerializer 



    def put(self,request,*args,**kwargs): 
     if Listen_Record.objects.filter(user=request.data['user'], songid=request.data['songid']).exists(): 

      tableid = Listen_Record.objects.values_list('id', flat=True).filter(user=request.data['user'], 
                       songid=request.data['songid']).get() 
      cnt = None 
      try: 
       cnt = Listen_Record.objects.get(id=tableid) 
       print(cnt) 
      except AttributeError: 

       cnt.listen_count = 0 

      cnt.listen_count += 1 
      print(cnt.listen_count) 
      cnt.save(['listen_count']) 
     return self.update(cnt,*args,**kwargs) 

    def post(self, request, *args, **kwargs): 
     if Listen_Record.objects.filter(user=request.data['user'], songid=request.data['songid']).exists(): 
      self.put(request, *args, **kwargs) 
     else: 
      return self.create(request,*args,**kwargs) 

基本的には、デフォルトのメソッドはPOSTになるだろうが、存在し、ユーザーIDとsongid場合、それは代わりに置いてくださいlisten_countフィールドをインクリメントします。私が今得ているエラーは、「UNIQUE制約に失敗しました:api_listen_record.id」です。

この機能を実装するより洗練された方法やエラーを修正する方法はありますか?

編集:私はそこにupdate_or_createメソッドがありますが、私はどのようにポスト/ポストメソッドでコンテキストでそれを使用するのですか?

+0

(http://stackoverflow.com/questions/14115318/create-django-model-or-update-if-exists)[存在する場合は、Djangoのモデルやアップデートを作成] – Dap

答えて

1

のだまされやすい人は、基本的には、デフォルトのメソッドはPOSTになりますが、ユーザーIDと songid場合、存在、それがlisten_count フィールドをインクリメントする代わりに置く必要があります。 「UNIQUE制約に失敗しました: api_listen_record.id」

これはあなたの主な問題です。前提は正しい要求を発行するためにクライアント上にあり、APIは要求を検証するためのものです。

あなたは本当にPOST対PUT強制する場合、レコードが存在し、リクエストがPOSTであれば、その後、あなたはそれを拒否すべきである:

from rest_framework.exceptions import ValidationError 

def post(self, request, *args, **kwargs): 
    filter = Listen_Record.objects.filter(user=request.data['user'], 
              songid=request.data['songid']) 
    if filter.exists(): 
     raise ValidationError({'error': 'POST not allowed, send PUT'}) 
    else: 
     return self.create(request,*args,**kwargs) 

同様に、あなたのPUTメソッドはまた、このようなチェックが必要です:

def put(self,request,*args,**kwargs): 
    try: 
     record = Listen_Record.objects.get(user=request.data['user'], 
              songid=request.data['songid']) 
     record.listen_count = record.listen_count + 1 
     record.save() 
     return self.update(record,*args,**kwargs) 
    except Listen_Record.DoesNotExist: 
     raise ValidationError({"error": "Send POST not PUT to create records"}) 
+0

感謝の可能性のある重複しました!これはうまくいきましたが、putリクエストはエラーを出します - "期待されるビューListenRecordCreateAPIViewはURLキーワード引数" pk "で呼び出されます。あなたのURL confを修正するか、ビューの' .lookup_field'属性を正しく設定してください。私の聴いた数はまだ更新されていますが、エラーを取り除くことが大好きです。 – hfz

0

あなたがDjangoの上にある場合は、そのドキュメントから

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon', defaults=updated_values) 

を取ら1つのドット7 例は、インスタンスを返し、作成したがdecievinglyブールここで作成したDjangoのupdate_or_createメソッドを使用することができます。

もこのCreate Django model or update if exists

関連する問題