2015-01-16 60 views
19

我有一個模型'MyModel'與很多領域,我想用PATCH方法更新字段'狀態'。我使用基於類的視圖。有沒有什麼辦法來實現PATCH?如何使用Django Rest Framework修補單個字段?

+0

你可以在你的視圖代碼中檢查'request.method =='PATCH'',然後做任何你想要的。 –

+0

我想知道如何在串行器類中處理這個問題。 – pnhegde

+0

串行器類不是必須瞭解請求方法的地方。所以我建議你檢查視圖類(如'APIView'),而不是串行器 –

回答

17

當初始化串行器時,串行器允許 partial updates by specifying partial=True。這是如何PATCH requests are handled默認in the generic views

serializer = CommentSerializer(comment, data=request.data, partial=True) 

這將讓你更新串行各個字段,或者所有的字段,如果你想,沒有任何的標準PUT要求的限制。

+12

這到底是什麼地方? –

+1

好問題@ScottSmith。看來文檔和其他來源僅引用這一行作爲部分更新的解決方案。但是如果他不知道把這行代碼放在哪裏,那就沒有用。 – JayGee

+1

「這是哪裏去的?」取決於你的觀點是如何寫的。這個答案假設你沒有使用通用視圖,而是在滾動你自己的視圖。 –

3

它似乎開箱即用支持。在您的瀏覽器API上,導航至HTML Form選項卡旁邊底部的模型詳細信息頁面,單擊Raw data,刪除除ID字段和要更改的字段之外的所有JSON字符串,然後單擊PATCH。部分PATCH更新被執行。

我使用djangorestframework==3.2.4,並沒有做任何事情來我ViewSets和串行器啓用它。

在這個exampe我們正在更新模型的布爾status_field領域,我使用jQuery 2.2.1。添加以下到<head>

<script src="{% static 'my_app/jquery.min.js' %}"></script> 
<script> 
$(document).ready(function(){ 
    var chk_status_field = $('#status_field'); 
    chk_status_field.click(function(){ 
     $.ajax({url: "{% url 'model-detail' your_rendering_context.id %}", 
      type: 'PATCH', timeout: 3000, data: { status_field: this.checked } 
     }) 
     .fail(function(){ 
      alert('Error updating this model instance.'); 
      chk_status_field.prop('checked', !chk_status_field.prop('checked')); 
     }); 
    }); 
}); 
</script> 

然後在<form>

<input type="checkbox" id="status_field" {% if your_rendering_context.status_field %} 
    checked {% endif %} > 

我選擇允許複選框改變,那麼在出現故障的情況下恢復它。但是,您可以用mousedown代替click,以便只在AJAX調用成功後更新複選框值。我認爲這會導致人們反覆點擊複選框進行慢速連接。

6

由於Kevin Brown聲明您可以使用partial=True,其中chefarov很好地澄清。

我只是想糾正他們說,你可以使用泛型自由,這取決於你所使用的HTTP方法:

  • 如果您正在使用PATCH HTTP方法就像問,你把它弄出來的盒子。你可以看到UpdateModelMixin代碼爲partial_update

    def partial_update(self, request, *args, **kwargs): 
        kwargs['partial'] = True 
        return self.update(request, *args, **kwargs) 
    
  • 對於來自PATCH不同任何HTTP方法,這可以通過只重寫get_serializer方法來完成如下:

    def get_serializer(self, *args, **kwargs): 
        kwargs['partial'] = True 
        return super(YOUR_CLASS, self).get_serializer(*args, **kwargs) 
    

這將創建序列化程序是部分的,其餘泛型將像魅力一樣工作,而不需要任何手動干預update/partial_update機制。

引擎蓋下

我使用的通用:generics.UpdateAPIView它使用具有這種代碼UpdateModelMixin

def update(self, request, *args, **kwargs): 
    partial = kwargs.pop('partial', False) 
    instance = self.get_object() 
    serializer = self.get_serializer(instance, data=request.data, partial=partial) 
    … 

所以,如果你重寫get_serializer功能,你其實可以覆蓋部分爭論並強迫它是真實的。

請注意,如果你只想部分HTTP方法,這使得這種方法更加困難。

我使用djangorestframework == 3.5.3

0

我這個一期一會掙扎,但它是使用通用視圖或通用的觀點和混入的組合非常簡單的實現。

在使用通用更新視圖(generics.UpdateAPIView)的情況下,只需使用下面的代碼,確保請求類型是PATCH:

class UpdateUser(generics.UpdateAPIView): 

    queryset = User.objects.all() 
    serializer_class = UserSerializer 

沒有別的了!

如果你在組合使用更新混入(mixins.UpdateModelMixin)與通用視圖(generics.GenericAPIView),使用下面的代碼,確保請求類型是PATCH:

class ActivateUser(mixins.UpdateModelMixin, generics.GenericAPIView): 

    serializer_class = UserSerializer 
    model = User 
    lookup_field = 'email' 

    def get_queryset(self): 
     queryset = self.model.objects.filter(active=False) 
     return queryset 

    def patch(self, request, *args, **kwargs): 
     return self.partial_update(request, *args, **kwargs) 

的第二個例子更復雜,向您展示如何覆蓋查詢集和查找字段,但您應該注意的代碼是修補程序功能。

相關問題