4

I'm new to using the Django Rest Framework and serialized data, I'm trying to update a nested serializer but ran into a wall, I've looked around but most people have problems in the serializers.py side while I can't even get into def update without an error, these are my classes:

Views.py

from django.shortcuts import render
from rest_framework import generics
from api.serializers import ProfileSerializer
from django.contrib.auth.models import User
from api.models import Profile
from django.http import JsonResponse

class ProfileView(generics.ListCreateAPIView):
    def get(self, request):
        profile = Profile.objects.filter(user_id=request.user.id)
        serializer = ProfileSerializer(profile, many=True)
        return JsonResponse(serializer.data, safe=False)
    def post(self, request, *args, **kwargs):
        profile = Profile.objects.filter(user_id=request.user.id)
        data = request.POST
        serializer = ProfileSerializer(profile, data=data, partial=True)
        if serializer.is_valid():
            serializer.save()
        else:
            print(serializer.errors)
        return JsonResponse(serializer.data, safe=False)

Serializers.py

from rest_framework import serializers
from django.contrib.auth.models import User
from api.models import Profile

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id','username','first_name','last_name','email','last_login','date_joined','is_active')

class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Profile
        fields = ('id','phone','birth_date','user')

        def update(self, instance, validated_data):
            #Cant get here
            print("hey")
            return instance

Sample structure

[
    {
        "id": 3,
        "phone": "XXXXXX",
        "birth_date": "2017-06-29",
        "user": {
            "id": 1,
            "username": "xxxxx",
            "first_name": "XXXXX",
            "last_name": "XXXX",
            "email": "[email protected]",
            "last_login": "2017-06-29T15:16:11.438818Z",
            "date_joined": "2017-06-23T16:48:38Z",
            "is_active": true
        }
    }
]

My current error: (Post Data: phone = 0000000)

AttributeError at /profile/
'QuerySet' object has no attribute '_meta'

Thank you!

3 Answers 3

8

Found myself in similar situation and I was able to solve as below.Hope it helps.

def update(self, instance, validated_data):
    user_data = validated_data.pop('user')
    user_serializer = UserSerializer()
    super(self.__class__, self).update(instance,validated_data)
    super(UserSerializer,user_serializer).update(instance.user,user_data)
    return instance
Sign up to request clarification or add additional context in comments.

1 Comment

You are instantiating a UserSerializer without an object or a "data" keyword argument. I believe this is because user_data is not exactly fit to pass to UserSerializer. But it is still an incorrect way to use the Serializer, isn't it?
6

You see this error because you are passing queryset instead of instance to serializer __init__. To solve error change this:

def post(self, request, *args, **kwargs):
    profile = Profile.objects.filter(user_id=request.user.id)

to this:

def post(self, request, *args, **kwargs):
    profile = Profile.objects.get(user_id=request.user.id)

in other words instead of queryset, which returned by filter you need Profile instance returned by get.

UPD

to update nested user try this (didnt test it, let me know if this have any errors):

def update(self, instance, validated_data):
    user = validated_data.get('user')
    instance.user.first_name = user.get('first_name')
    instance.user.save()

    print("hey")
    return instance

6 Comments

Awesome! That works for normal updating, I can change the data on the upper level (phone) but could you help me out in updating the data for the nested set? (Changing the username for example) I gave it a try posting user.email = something but got the following error The .update() method does not support writable nested fields by default. how do I write my custom update method to do that then? Thanks again
I still get the same error, it looks like it would work, but I don't seem to be getting into that function at all, when I post data it tries the default update instead of my custom one, do I need to specify it in my view using .update() or something?
@Amirgem oh, I see, remove update from Meta class. This should be inside Serializer class directly, an the same level as Meta.
I was about to type that that was the mistake haha, thanks never!!
I want to show the data into the fields at the time of updation do you know how do we do that in nested serializing...... because otherwise I am getting null or blank fields, so if I edit one field it shows me an error, that these fields can't be blank or null.... please help.... Thank You
|
0

I faced a similar issue and resolved it using a workaround. First let me explain my scenario. When a SUBMIT button is pressed on a JS page, it will trigger a REST API which will increment the count of an existing DB item by 1. So I parsed the contents of the incoming JSON request into a variable, say A. But since this variable was immutable, so I created a new variable say X, and then added the value in a format which could be sent to the serializable class like so:- X = {'item_name': A["item_name"], 'count_of_votes': last_count + 1} Then serializer_class_Object = serializer_class(existing_object_ref, data=X)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.