2

我在django rest框架中使用以下代碼來實現put和patch功能。 PATCH(partial_update)工作正常,但是,爲PUT提供更少的字段將不會像PUT請求應該那樣替換整個資源。例如,如果數據看起來像下面這樣:在Django rest框架中HTTP PUT無法正常工作

{ 
"id": 6, 
"name": "crticial MVP", 
"description": "getting things done", 
"end": "2012-02-18" 
} 

如果我試圖用(上http://localhost:800/api/sprints/6/)下列數據的PUT:

{ 
    "name": "critical MVP2", 
    "end": "2012-02-18" 
} 

該調用應設置說明無。但是描述保留了它的價值,就好像我正在做PATCH一樣。我將如何在更新功能中強制執行資源替換?

PS:在初始化串行器進行更新時,我設置了partial = False。

views.py:

class SprintViewSet(viewsets.ModelViewSet): 
    queryset = Sprint.objects.order_by('end') 
    serializer_class = SprintSerializer 
    def update(self, request, *args, **kwargs): 
     sprint=self.get_object()       
     serializer = SprintSerializer(sprint, data=request.data, partial=False, 
context={'request': request, 'view':self, 'format':None}) 
     serializer.is_valid(raise_exception=True)  
     serializer.save() 
     return Response(serializer.data) 
    def partial_update(self, request, *args, **kwargs): 
     instance = self.get_object() 
     serializer = SprintSerializer(instance, data=request.data, partial=True, 
context={'request': request, 'view':self, 'format':None}) 
     serializer.is_valid(raise_exception=True) 
     new_instance = serializer.save() 
     return Response(serializer.data) 

serializers.py:

class SprintSerializer(serializers.ModelSerializer): 
    links = serializers.SerializerMethodField() 
    class Meta:  
     model = Sprint    
     fields = ('id', 'name', 'description', 'end', 'links') 
    def get_links(self, obj): 
     request = self.context['request'] 
     return { 
       'self': reverse('sprint-detail', 
       kwargs={'pk': obj.pk},request=request), 
       } 

models.py

class Sprint(models.Model): 
    name = models.CharField(max_length=100, blank=True, default='') 
    description = models.TextField(blank=True, default='') 
    end = models.DateField(unique=True) 
    def __str__(self): 
     return self.name or _('Sprint ending %s') % self.end 

回答

3

PUT期望完整數據對象被傳遞在,因此任何模型上的屬性被傳入的數據替換。但是這需要完整的數據obj ect被傳入,所以如果你不通過一個字段,那麼它將被忽略,這取決於數據的發送方式。

如果您使用表單數據發送數據(不帶JSON的AJAX或HTML <form>),則該字段將被完全忽略。這主要是因爲某些瀏覽器沒有發送某些字段(如複選框),如果該值未設置,DRF在這些情況下會手動覆蓋它。

如果您使用的是JSON並且該字段不是必需的(這似乎是您的情況),那麼DRF將只會在該密鑰傳入請求時覆蓋該值。這是因爲PUT應該包含一個完整的數據對象,並且DRF根據此假設做出一些假設。