1

hi im trying to save a form data into db. i provided print of requset.data for you as you see requirement have two items.

i want to save each item in database i used for loop to save each item of list but the loop will save each character of item like h-e-l,... in table row... where is my mistake ... thanks

also print of request.data.get('requirement') will retun second item

this is print of request.data in sever:

<QueryDict: {'requirement': ['hello', 'bye'], 'audience': ['adasd'], 'achievement': ['asdasd'], 'section': ['410101010'], 'title': ['asdasd'], 'mini_description': ['asdad'], 'full_description': ['asdasd'], 'video_length': ['10101'], 'video_level': ['P'], 'price': [''], 'free': ['true'], 'image': [<InMemoryUploadedFile: p.gif (image/gif)>]}>

view:

class StoreCreateAPIView(generics.CreateAPIView):
    parser_classes = (MultiPartParser, FormParser)
    permission_classes = [IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

    def post(self, request, *args, **kwargs):
        if request.method == 'POST':
            print(request.data)
            file_serial = ProductSerializer(data=request.data, context={"request": request})
            if file_serial.is_valid():
                file_serial.save(author_id=request.user.id)
                requirement = request.data['requirement']
                audience = request.data.get('audience')
                achievement = request.data.get('achievement')
                sections = request.data.get('section')

                print(request.data['requirement'])
                pid = file_serial.data.get('product_id')
                for item in requirement :
                    req = ProductRequiredItems(
                        item = item,
                        product_id = pid
                    )
                    req.save()

1 Answer 1

3

First of all, overriding CreateAPIView's post method in your code makes your custom perform_create method useless, unless you explicitly call it from within your customized post method. Otherwise it will never be called.

also print of request.data.get('requirement') will retun second item

It does return the last item as per Django docs for QueryDict.__getitem__(key).

i want to save each item in database i used for loop to save each item of list but the loop will save each character of item like h-e-l,...

This is because of the above functionality of QueryDict. When you do:

requirement = request.data['requirement']
# requirement = request.__getitem__('requirement')

it will call QueryDict.__getitem__(key) method and thus return only the last item (which is string in you example).

Answer:

You can simply override CreateAPIView's create method, and let your serializer handle all the rest.

# views.py
from django.shortcuts import render
from rest_framework import generics, status
from rest_framework.response import Response
from .models import MyObj
from .serializers import MyObjSerializer

class MyObjView(generics.CreateAPIView):
    serializer_class = MyObjSerializer
    queryset = MyObj.objects.all()

    def create(self, request, *args, **kwargs):
        # The QueryDicts at request.POST and request.GET will be immutable 
        # when accessed in a normal request/response cycle. 
        # To get a mutable version you need to use QueryDict.copy().
        req_data = request.data.copy()
        requirements = req_data.pop('requirement')
        serializers_data = []
        for requirement in requirements:
            req_data ['requirement'] = requirement
            serializer = self.get_serializer(data=req_data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            serializers_data.append(serializer.data)
        return Response(serializers_data, status=status.HTTP_201_CREATED)

# serializers.py
from rest_framework import serializers
from .models import MyObj

class MyObjSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyObj
        fields = '__all__'

Have a look at DRF CreateModelMixin. It defines create & perform_create methods that are used used in CreateAPIView upon executing POST request. I just altered them slightly to handle your specific case.

Hope it helps.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.