2017-10-17 2 views
0

Je suit la structure du modèle,django cadre reste inverse champ étranger n'a pas mis à jour, le retour liste vide

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) 

et les serializers,

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') 

et Bill api en utilisant viewset,

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

maintenant si je veux mise à jourBill api avec la liste des Routes selon la structure de sérialiseur, comme celui-ci

**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": "[email protected]", 
     "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": "[email protected]", 
     "bill": 29 
     }  
     ] 
     } 

seulement mettre à jour Bill attribut, dire que je mis à jour total_bill_amount la formule 301 à 700, son succès mis à jour mais routes liste sont vides comme celui-ci,

**Result after calling put method** 

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

qu'est-ce qui ne va pas je fais ici? pourquoi routes n'est pas mis à jour?

+0

Vous devez lire la documentation sur les sérialiseurs imbriqués. – Linovia

+0

pouvez-vous être précis où est le problème avec mon code? @Linovia – RTan

Répondre

1

Par défaut, DRF ne mettra pas à jour routes. Vous devez remplacer update méthode de votre sérialiseur, comme ceci:

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 

Hope it helps!

+0

Malheureusement, ce n'est pas woking, en fait 'validated_data' contient' {'created_by': , 'total_bill_amount': 704} ', ne contient pas' routes', donc il n'entre pas le prochain bloc "if". @Jahongir Rahmonov – RTan

+0

@ Md.TanvirRaihan vous devez retirer 'read_only = True' de' RouteSerializer (many = True, read_only = True) ' –

+0

après avoir enlevé' read_only = True' son erreur d'élévation suivante 'The' .update() ' La méthode ne prend pas en charge les champs imbriqués en écriture par défaut. Ecrivez une méthode '.update()' explicite pour le sérialiseur 'conveyance.serializers.BillSerializer' ou définissez' read_only = True' sur les champs de sérialiseurs imbriqués. ' – RTan