I'm trying to call an existing class based view for Model1 from another class based view of Model2. The data I'm receiving from the front end in JSON has the data for Model1 and Model 2 together in below format:
request.data format:
{
"model1": {
"key1": "val1"
},
"model2": {
"key2": "val2"
}
}
In my Model1View, I'm doing some additional things which I want to do whenever I have to save some new data to Model1. So I intend on using the same view. (These additional things include creating other model instances etc).
Objective: When I call Model2View, I want to seperate the request data for Model1 and call Model1View first. Once I successfully get a response from this view, I want to use the model1_id (primary key of Model1), to add to the request data and save Model2.
Problem: While testing with this view, I'm getting an error:
django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
Models:
from django.db import models
class Model1(models.Model):
model1_id = models.AutoField(primary_key=True)
key1 = models.CharField(max_length=20, blank=False, null=False)
class Model2(models.Model):
model2_id = models.AutoField(primary_key=True)
key2 = models.CharField(max_length=20, blank=False, null=False)
model1_id = models.ForeignKey('Model1', blank=False, null=False, on_delete=models.PROTECT)
Serializers:
from rest_framework import serializers
from .models import *
class Model1Serializer(serializers.ModelSerializer):
class Meta:
model = Model1
fields = '__all__'
class Model2Serializer(serializers.ModelSerializer):
class Meta:
model = Model2
fields = '__all__'
Views:
from django.shortcuts import render
from rest_framework import generics
from rest_framework.response import Response
from rest_framework import status
from .models import *
from .serializers import *
class Model1View(generics.ListCreateAPIView):
queryset = Model1.objects.all()
serializer_class = Model1Serializer
def post(self, request, *args, **kwargs):
if ('data' in kwargs):
request.data.update(kwargs.get('data'))
# Call super to save the data in Model1
response = super().post(request, *args, **kwargs)
# Do some additional things
return Response(response.data, status.HTTP_201_CREATED)
class Model2View(generics.ListCreateAPIView):
queryset = Model2.objects.all()
serializer_class = Model2Serializer
def post(self, request, *args, **kwargs):
# Get Model1 data and Model2 data from request
model1_data = request.data.pop("model1")
model2_data = request.data.pop("model2")
# Call Model1View to create Model1 Instance
model1_response = Model1View.as_view()(request._request, data=model1_data)
# Save Model1 Instance ID to data and then save Model2 Instance
model2_data["model1_id"] = model1_response['model1_id']
model2_serializer = Model2Serializer(data=model2_data)
if model2_serializer.is_valid():
model2_serializer.save()
return Response(model2_serializer.data, status.HTTP_201_CREATED)
return Response(model2_serializer.errors, status.HTTP_400_BAD_REQUEST)
Some trials: Removing the request.data.pop statements resolves the error but then, how do I extract the data from the request? If I in anyway interact with the request object, either by copying it or updating data etc, before I call the Model1View, I end up getting the same error.