如果超级密钥不存在,Django会创建行,否则更新它

时间:2016-11-28 16:14:57

标签: django python-3.x django-models django-views django-rest-framework

我正在尝试使用django和django休息框架创建音乐webapp - 问题在于实现监听记录计数器。每当用户播放歌曲时,该song_id的计数器,user_id应该增加。

我的模型看起来像这样,

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,但如果存在userid和songid,则应该PUT而不是增加listen_count字段。我现在得到的错误是" UNIQUE约束失败:api_listen_record.id"

是否有更优雅的方式来实现此功能或如何修复错误?

编辑:我知道有update_or_create方法,但我如何在使用django rest框架的post / put方法的上下文中使用它?

2 个答案:

答案 0 :(得分:1)

  

基本上,默认方法是POST,但如果是userid和   songid,存在,它应该PUT而不是增加listen_count   领域。我现在得到的错误是“UNIQUE约束失败:   api_listen_record.id“

这是你的主要问题。前提是客户端发出正确的请求,因为API就是验证请求。

如果你真的想强制执行PUT与POST,那么如果记录存在,并且请求是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"})

答案 1 :(得分:0)

如果您使用的是django 1 dot 7,则可以使用django的update_or_create方法。 从他们的文档中获取的示例

Firm Year  V1  V2 V3
AAA  2001  0   8   2    
AAA  2002  10  4   2    
BBB  1999  0   8   8    
BBB  2000  7   0   6    
BBB  2001  10  NA  1    
BBB  2002  1   5   8    
CCC  2001  2   8   0    
CCC  2002  NA  3   10   

返回一个实例,并在创建的地方创建了一个布尔值。

也是这个Create Django model or update if exists

的骗局