2016-01-05 45 views
2

我在我的DataSerliazer中有一个自定义验证函数,它检查两个参数(mrange,mthreshold)。验证功能检查发布时只需设置其中一个参数。Django Rest框架:对HTTP POST和PUT的不同验证

class DataSerializer(serializers.ModelSerializer): 
    emails = serializers.ListField(child = serializers.EmailField()) 
    class Meta: 
     model = AIData 
     fields = ('id', 'name', 'created', 'username', 'token', 
        'expression','key','threshold' ,'evaluator', 'range','emails','metric_name', 'status') 

    def validate(self,attrs): 
mrange = attrs.get("metric_range") 
     mthreshold = attrs.get("metric_threshold") 
    if (mrange == None or mrange == " ") and (mthreshold == None or mthreshold == " "): 
      raise serializers.ValidationError({'error': 'Cannot have both range and threshold empty'}) 
     elif mrange != None and mthreshold != None: 
      raise serializers.ValidationError({'error': 'Cannot set both range and threshold'}) 

在我views.py文件

@api_view(['GET','PUT', 'DELETE']) 
def ai_detail(request, token, id): 
     ai = None 
     try: 
       ai = AIData.objects.get(id=id) 
     except AIData.DoesNotExist: 
       return Response(status=status.HTTP_404_NOT_FOUND) 

     if request.method == 'GET': 
       serializer = DataSerializer(ai) 
       if serializer.data['token'] == token: 
         return Response(serializer.data) 
       else: 
         return Response({'error': 'Not allowed to access'}, status=status.HTTP_400_BAD_REQUEST) 

     elif request.method == 'PUT': 
       serializer = AlAnotherSerializerMethod(alert, data=request.data, partial=True) 
       if serializer.is_valid(): 
         // updating code 

目前,我必须写anthor AIAnotherSerializerMethod,这样,它不隐式调用DataSerializer的验证功能。这是为了避免在创建对象时检查2个参数。一旦对象被创建,我不想再检查相同的功能。有没有更好的方法来做同样的事情?我最好避免为同一模型编写2个串行器。

回答

0

你可以通过context data到串行其中可能包括请求本身。

您可以通过调用self.context随时访问序列化程序中任何位置的上下文。

该解决方案确实可以更轻松地提供上下文数据,而不会覆盖__init__

0

就我所知,rest-framework库没有这样的东西。

我这样做的方式是覆盖__init__并添加自己的变量来检查这一点。

class DataSerializer(serializers.ModelSerializer): 
    emails = serializers.ListField(child = serializers.EmailField()) 
    class Meta: 
     model = AIData 
     fields = ('id', 'name', 'created', 'username', 'token', 
        'expression','key','threshold' ,'evaluator', 'range','emails','metric_name', 'status') 

    def __init__(self, *args, **kwargs): 
     super(DataSerializer, self).__init__(*args, **kwargs) 
     self._request_method = kwargs.get('request_method', 'GET') 

    def validate(self,attrs): 
     if self._request_method == 'GET': 
      # GET logic 
     elif self._request_method in ('PUT', 'POST'): 
      # Put or Post logic 

然后我会使用这样的:

serializer = DataSerializer(ai, request_method=request.method)