Vla*_*lad 26 django django-rest-framework
我不是很熟悉Django REST框架,并且已经尝试了很多东西但是无法使我的PATCH请求工作.
我有一个模型序列化器.这与我用来添加新条目的那个相同,理想情况下我想在更新条目时重复使用.
class TimeSerializer(serializers.ModelSerializer):
class Meta:
model = TimeEntry
fields = ('id', 'project', 'amount', 'description', 'date')
def __init__(self, user, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
super(TimeSerializer, self).__init__(*args, **kwargs)
self.user = user
def validate_project(self, attrs, source):
"""
Check that the project is correct
"""
.....
def validate_amount(self, attrs, source):
"""
Check the amount in valid
"""
.....
Run Code Online (Sandbox Code Playgroud)
我试图使用基于类的视图:
class UserViewSet(generics.UpdateAPIView):
"""
API endpoint that allows timeentries to be edited.
"""
queryset = TimeEntry.objects.all()
serializer_class = TimeSerializer
Run Code Online (Sandbox Code Playgroud)
我的网址是:
url(r'^api/edit/(?P<pk>\d+)/$', UserViewSet.as_view(), name='timeentry_api_edit'),
Run Code Online (Sandbox Code Playgroud)
我的JS电话是:
var putData = { 'id': '51', 'description': "new desc" }
$.ajax({
url: '/en/hours/api/edit/' + id + '/',
type: "PATCH",
data: putData,
success: function(data, textStatus, jqXHR) {
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我希望我的描述能够更新,但是我得到了需要字段的错误(对于'project'和所有其他字段).验证失败.如果添加到AJAX调用所有字段,它仍然需要检索"项目"时失败.
我也尝试过自己的看法:
@api_view(['PATCH'])
@permission_classes([permissions.IsAuthenticated])
def edit_time(request):
if request.method == 'PATCH':
serializer = TimeSerializer(request.user, data=request.DATA, partial=True)
if serializer.is_valid():
time_entry = serializer.save()
return Response(status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)
由于相同的原因(字段的验证失败),这对于部分更新不起作用,即使我已经发送了所有字段,它也不起作用.它创建一个新条目,而不是编辑现有条目.
我想重新使用相同的序列化器和验证,但我愿意接受任何其他建议.此外,如果某人有一段工作代码(ajax代码 - > api view-> serializer)会很棒.
ram*_*win 19
class DetailView(APIView):
def get_object(self, pk):
return TestModel.objects.get(pk=pk)
def patch(self, request, pk):
testmodel_object = self.get_object(pk)
serializer = TestModelSerializer(testmodel_object, data=request.data, partial=True) # set partial=True to update a data partially
if serializer.is_valid():
serializer.save()
return JsonResponse(code=201, data=serializer.data)
return JsonResponse(code=400, data="wrong parameters")
Run Code Online (Sandbox Code Playgroud)
文档
您无需编写partial_update
或覆盖该update
方法.只需使用该patch
方法.
请确保您有"补丁"中http_method_names.或者你可以像这样写:
@property
def allowed_methods(self):
"""
Return the list of allowed HTTP methods, uppercased.
"""
self.http_method_names.append("patch")
return [method.upper() for method in self.http_method_names
if hasattr(self, method)]
Run Code Online (Sandbox Code Playgroud)
如文件中所述:
默认情况下,序列化程序必须传递所有必填字段的值,否则会引发验证错误.您可以使用partial参数以允许部分更新.
update
在视图中覆盖方法:
def update(self, request, *args, **kwargs):
instance = self.get_object()
serializer = TimeSerializer(instance, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save(customer_id=customer, **serializer.validated_data)
return Response(serializer.validated_data)
Run Code Online (Sandbox Code Playgroud)
或者只是partial_update
在视图中覆盖方法:
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
Serializer调用ModelSerializer的更新方法(参见来源):
def update(self, instance, validated_data):
raise_errors_on_nested_writes('update', self, validated_data)
# Simply set each attribute on the instance, and then save it.
# Note that unlike `.create()` we don't need to treat many-to-many
# relationships as being a special case. During updates we already
# have an instance pk for the relationships to be associated with.
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
Run Code Online (Sandbox Code Playgroud)
Update将validated_data值推送到给定实例.请注意,更新不应假定所有字段都可用.这有助于处理部分更新(PATCH请求).
该patch
方法适用于我viewset
在 DRF 中使用。我正在改变你的代码:
class UserViewSet(viewsets.ModelViewSet):
queryset = TimeEntry.objects.all()
serializer_class = TimeSerializer
def perform_update(self, serializer):
user_instance = serializer.instance
request = self.request
serializer.save(**modified_attrs)
return Response(status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
26940 次 |
最近记录: |