django rest框架反向外部字段未更新,返回空列表

时间:2017-10-17 06:18:23

标签: python django django-rest-framework

我有以下模型结构,

class Bill(models.Model):
    created_on = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='bill_created_by')

    total_bill_amount = models.IntegerField(blank=True, null=True)

class Route(models.Model):
    start_time = models.DateTimeField(auto_now=False,blank=True, null=True)
    end_time = models.DateTimeField(auto_now=False,blank=True, null=True)
    start_lat = models.FloatField(default=0.0,blank=True, null=True)
    start_lon = models.FloatField(default=0.0,blank=True, null=True)
    end_lat = models.FloatField(default=0.0,blank=True, null=True)
    end_lon = models.FloatField(default=0.0,blank=True, null=True)
    distance = models.FloatField(default=0.0,blank=True, null=True)
    transport = models.CharField(max_length=300,blank=True, null=True, choices=ROUTE_MODE, default=ROUTE_MODE[0])
    fare = models.IntegerField(blank=True, null=True)
    purpose = models.CharField(max_length=1000, blank=True, null=True)
    bill = models.ForeignKey(Bill, related_name="routes",on_delete=models.CASCADE, blank=True, null=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,blank=True, null=True, related_name='routes', max_length=255)

和序列化程序,

class BillSerializer(ModelSerializer):
    routes = RouteSerializer(many=True, read_only=True)
    class Meta:
        model = Bill
        fields = ('id','created_on','created_by','total_bill_amount','routes') 

lass RouteSerializer(ModelSerializer):
    all_directions = AllDirectionSerializer(many=True, read_only=True)
    user = ReadOnlyField(source='user.email')
    bill = ReadOnlyField(source='bill.id')
    class Meta:
        model = Route
        fields = ('id','start_time','end_time','start_lat','start_lon','fare',
        'end_lat','end_lon','distance','transport','all_directions','user', 'bill')
使用viewset

Bill api,

class BillViewSet(viewsets.ModelViewSet):
    queryset = Bill.objects.all()
    serializer_class = BillSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)

现在,如果我想根据序列化程序结构更新 Bill api和Routes列表,就像这样

**calling put method on Bill api where Bill id is 29**

   {
   "id": 29,
   "created_on": "2017-10-15T10:05:19.786057Z",
   "created_by": 4,
   "total_bill_amount": 301,
   "routes": [
    {
        "id": 31,
        "start_time": null,
        "end_time": null,
        "start_lat": 23.77201,
        "start_lon": 90.3602333333333,
        "fare": 0,
        "end_lat": 0.0,
        "end_lon": 0.0,
        "distance": 0.0,
        "transport": "BUS",
        "all_directions": [],
        "user": "tanvir@gmal.com",
        "bill": 29
       },
       {
        "id": 32,
        "start_time": null,
        "end_time": null,
        "start_lat": 23.7715316666667,
        "start_lon": 90.3604483333333,
        "fare": 0,
        "end_lat": 0.0,
        "end_lon": 0.0,
        "distance": 0.0,
        "transport": "BUS",
        "all_directions": [],
        "user": "tanvir@gmail.com",
        "bill": 29
       }    
       ]
       }

它只更新了Bill属性,比如我更新了total_bill_amount表单301到700,它已成功更新但routes列表变为空,如下所示,

**Result after calling put method**

{
"id": 29,
"created_on": "2017-10-15T09:47:50.913255Z",
"created_by": 4,
"total_bill_amount": 700,
"routes": []
}

我在这里做错了什么?为什么routes没有更新?

1 个答案:

答案 0 :(得分:1)

默认情况下,DRF不会更新routes。您应该覆盖序列化程序的update方法,如下所示:

class BillSerializer(ModelSerializer):
    routes = RouteSerializer(many=True, read_only=True)
    class Meta:
        model = Bill
        fields =('id','created_on','created_by','total_bill_amount','routes')

    def update(self, instance, validated_data)
        instance = super().update(instance, validated_data)

        routes = validated_data.get('routes')

        if routes:
            for route_info in routes:
                Route.objects.filter(id=route_info['id']).update(**route_info)

        return instance

希望它有所帮助!