django更新数据库中的记录

时间:2018-02-06 19:57:53

标签: django class

我尝试使用代码来更新表中的记录,但这会创建新记录而不是更新。我需要的是更新表中的resevedplaces而不是创建新记录

这是我的代码,谢谢:

观点:

class ReservationCancelView(mixins.RetrieveModelMixin,        mixins.ListModelMixin, mixins.DestroyModelMixin,               mixins.CreateModelMixin,mixins.UpdateModelMixin,                viewsets.GenericViewSet):
#Model = Reservation
serializer_class = ReservationCSerializer
permission_classes = (permissions.IsAuthenticated,)    

def get_queryset(self):
    resid = self.request.POST.get('id')  
    Res= Reservation.objects.get(id=resid)
    #Res.reservedplaces =F('reservedplaces ') - 1
    #Res.save()
    return Res

def post(self, request, token=None, format=None):
    resid = self.request.POST.get('id')  
    travel_id = self.request.POST.get('travel_id')  

    Res= Reservation.objects.get(id=resid)         
    Res.reservedplaces =F('reservedplaces ') - 1
    Res.travel_id = travel_id
    Res.save()

串行

class ReservationCSerializer(serializers.ModelSerializer):
    user = Serializers.PrimaryKeyRelatedField(read_only=True,default=serializers.CurrentUserDefault())

  class Meta:
    model = Reservation
    fields = ('__all__')

urls.py

router.register(r'cancelreservation', ReservationCancelView,'reservationcancel')

这是发布请求:

 let data = {
               'travel_id': rideID ,
               'id' : resID,
               'address' : address,
               'reservedplaces': nbplaces            
              };

   $.ajax({
        method: 'POST',
        url: '/api/cancelreservation/',
        datatype: 'json',
        headers: {
            'Authorization': 'Token ' + localStorage.token
        },
        data: data,
        success: function (response) {
        }
    })

1 个答案:

答案 0 :(得分:1)

Django rest框架并不像你使用的那样使用post()。

来自documentation

  

ViewSet类只是一种基于类的View,它不提供任何方法处理程序,如.get()或.post(),而是提供诸如.list()和.create()之类的操作。 。

您要扩展的GenericViewSet将POST请求路由到CreateModelMixin中定义的create()方法。它将PUT路由到UpdateModelMixin中的update()

您的代码创建新实例的原因是因为调用了默认的create()方法而不是post()方法。进行更新的正确方法是使用" PUT"方法而不是。这将映射到UpdateModelMixin中的update()方法。然后覆盖更新。

此外,您的路由器将为您创建网址模式。它并不简单地通过相同的URL路由所有内容,因为它需要一个pk来更新和检索。 routers上的文档告诉我们PUT方法允许在以下URL:

{前缀} / {查找} /

因此,在您的情况下,您需要将您的请求发送到' / api / cancelreservation / OBJECT_PK /'

这是我会尝试的。

观点:

class ReservationCancelView(mixins.RetrieveModelMixin,
                            mixins.ListModelMixin, mixins.DestroyModelMixin, mixins.CreateModelMixin,
                            mixins.UpdateModelMixin, viewsets.GenericViewSet):
    serializer_class = ReservationCSerializer
    permission_classes = (permissions.IsAuthenticated,)    
    queryset = Reservation.objects.all()

        def update(self, request, *args, **kwargs):
            # This retrieves the model instance by the pk in the url
            reservation = self.get_object()
            # request.data is a dictionary containing your data.
            # We copy it because you wanted to change 'reservedplaces' but it is immutable, and copying it makes it mutable
            data = request.data.copy()
            # This edits 'reservedplaces' before we initializes the serializer
            data['reservedplaces'] -= 1
            # This initializes the serializer
            serializer = self.get_serializer(reservation, data=data)
            # Always validate the data
            serializer.is_valid(raise_exception=True)
            # perform_update() will save the data to the database
            self.perform_update(serializer)
            # Return the JSON Response
            return Response(serializer.data)

请求:

let data = {
           'travel_id': rideID ,
           'id' : resID,
           'address' : address,
           'reservedplaces': nbplaces            
          };

$.ajax({
    method: 'PUT',
    url: '/api/cancelreservation/' + resID + '/',
    datatype: 'json',
    headers: {
        'Authorization': 'Token ' + localStorage.token
    },
    data: data,
    success: function (response) {
        console.log("Success!");
    }
})

我无法在不看你的模型的情况下测试上面的代码,但是试一试,希望它有效。如果您需要更多帮助,请发布预订模式。