2017-07-23 4 views
0

Modell zu aktualisieren:Django PUT-Anforderung Serializer ruhen nicht mit Fremdschlüssel

class Task(models.Model): 
    user = models.ForeignKey(User, blank=True) 
    what_task = models.CharField(max_length=100,) 

    #This helps to print in admin interface 
    def __str__(self): 
     return u"%s" % (self.what_task) 


class Step(models.Model): 
    task = models.ForeignKey(Task, related_name='steps', on_delete=models.CASCADE,) 
    what_step = models.CharField(max_length=50, blank=True,) 

    #This helps to print in admin interface 
    def __str__(self): 
     return u"%s" % (self.what_step) 

Und ich habe Serializer geschrieben:

class StepSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Step 
     exclude = ('task',) 

class TaskSerializer(serializers.ModelSerializer): 
    steps = StepSerializer(many=True) 
    class Meta: 
     model = Task 
     fields = '__all__' 


    def create(self, validated_data): 
     steps_data = validated_data.pop('steps') 
     task = Task.objects.create(**validated_data) 
     for step_data in steps_data: 
      Step.objects.create(task=task, **step_data) 
     return task 

    def update(self, instance, validated_data): 
     steps_data = validated_data.pop('steps') 

     instance.what_task = validated_data.get('what_task', instance.what_task) 
     instance.how_often = validated_data.get('how_often', instance.how_often) 
     instance.how_important = validated_data.get('how_important', instance.how_important) 
     instance.why_perform = validated_data.get('why_perform', instance.why_perform) 
     instance.why_important = validated_data.get('why_important', instance.why_important) 
     instance.possible_improvement = validated_data.get('possible_improvement', instance.possible_improvement) 
     instance.existing_solutions = validated_data.get('existing_solutions', instance.existing_solutions) 
     instance.how_important_improvement = validated_data.get('how_important_improvement', instance.how_important_improvement) 
     instance.advantages_of_improvement = validated_data.get('advantages_of_improvement', instance.advantages_of_improvement) 

     instance.save() 
     for step_data in steps_data: 
      Step.objects.update(task=task, **step_data) 
     return instance 

Meine Ansicht:

@api_view(['GET', 'POST']) 
def task_list(request): 
    """ 
    List all tasks, or create a new task. 
    """ 
    if request.method == 'GET': 
     print(request.user) 
     tasks = Task.objects.filter(user=request.user.id) 
     serializer = TaskSerializer(tasks, many=True) 
     return Response(serializer.data) 

    elif request.method == 'POST': 
     serializer = TaskSerializer(data=request.data) 
     print(request.data) 
     if serializer.is_valid(): 
      serializer.save(user=request.user) 
      return Response(serializer.data, status=status.HTTP_201_CREATED) 
     else: 
      return Response(
       serializer.errors, status=status.HTTP_400_BAD_REQUEST) 


@api_view(['GET', 'PUT', 'DELETE']) 
def task_detail(request, id): 
    """ 
    Get, udpate, or delete a specific task 
    """ 
    try: 
     task = Task.objects.get(id=id) 
    except Task.DoesNotExist: 
     return Response(status=status.HTTP_404_NOT_FOUND) 

    if request.method == 'GET': 
     serializer = TaskSerializer(task) 
     return Response(serializer.data) 

    elif request.method == 'PUT': 
     serializer = TaskSerializer(task, data=request.data) 
     if serializer.is_valid(): 
      serializer.save(user=request.user) 
      return Response(serializer.data) 
     else: 
      return Response(
       serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

    elif request.method == 'DELETE': 
     task.delete() 
     return Response(status=status.HTTP_204_NO_CONTENT) 

Meine GET und POST-Anfragen funktionieren korrekt (erste Funktion in Sichten), meine Aufgaben und zugehörigen Schritte werden in einer einzigen Anfrage erstellt, wie immer PUT Anfrage ist falsch, ich bin mir nicht sicher, ob ich die Schritte richtig aktualisiere; Wenn ich die For-Schleife aus dem Serialisierer auskommentiere, wird die Aufgabe erfolgreich aktualisiert.

Was und wie soll ich ändern, damit ich eine bestimmte Aufgabe mit den zugehörigen Schritten aktualisieren kann?

+0

Beantwortet Ihre Frage nicht, aber ... sollten Sie sich mit den Viewsets von DRF beschäftigen, die alle Voreinstellungen wie die, die Sie automatisch implementieren, ausführen. – spectras

+0

Was meinst du mit "PUT" Anfrage ist falsch? Gibt es eine Ausnahme? –

+0

Ich habe meine Frage aktualisiert. – Nitish

Antwort

1

In Ihrer for-Schleife Sie jede vorhandene Aufgabe aktualisieren (innen update, setzen Sie die neuen Werte):

Step.objects.update(task=task, **step_data) 

, statt vor der Schleife, sollten Sie alle Schritte für diese Aufgabe löschen und die neue erstellen Schritte:

... 
    Step.objects.filter(task=instance).delete() 
    for step_data in steps_data: 
     Step.objects.create(task=instance, **step_data) 
... 

Ein effizienterer Ansatz wäre es, alle Schritte zu finden, die sie existiert nicht (auf id basiert) in validated_data und löschen, die Schritte mit einer ID aktualisieren, eine solche ohne ids erstellen.

+0

Danke! Ich benutze deine Lösung! – Nitish

Verwandte Themen