我有以下模型结构,
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
没有更新?
答案 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
希望它有所帮助!