0

Iam using Django 3.2 with Restframework. I have a Model as a for a Primary key named Tag and a Model connected as a foreign key named TagItem.

I tried to get a nested JSON output for it but its not working as expected.

Models.py

class Tags(models.Model):
    tagId = models.CharField(primary_key=True, max_length=100,default=1)
    section = models.CharField(max_length=100)
class TagItem(models.Model):
    tagId= models.ForeignKey(Tags, on_delete=models.CASCADE,default=1)
    select = models.BooleanField(default=False)
    name = models.CharField(max_length=50)

views.py

def get_tag_details(request):
    if request.method == 'GET':
        tag = Tags.objects.all()
        tagitem = TagItem.objects.all()

        TagSerializeobj = TagsSerializer(tag,many=True)
        TagItemSerializeobj = TagItemSerializer(tagitem, many=True)
        result = {}
        result['tag'] = TagSerializeobj.data
        for item in TagItemSerializeobj:
            if item.tagId == result['tag'].tagId:
                result['tagItem'] = item
        return Response(result)

Error: 'ListSerializer' object is not iterable How to iterate of get items nested under related Tags only.

Required output

{
      "id": 1,
      "section": "crafts",
      "items": [
        {
          "id": "10",
          "select": false,
          "name": "Wood"
        },
        {
          "id": "11",
          "select": false,
          "name": "Clay"
        }
    ]
},
   {
      "id": 2,
      "section": "states",
      "items": [
        {
          "id": "20",
          "select": false,
          "name": "Andhra Pradesh"
        },
        {
          "id": "21",
          "select": false,
          "name": "Arunachal Pradesh"
        },
    ]
}

2 Answers 2

1

You don't need to do all those processing in your views. ModelSerializer can do it for you, so you can just define a model serializer for TagItem that is nested on a model serializer for Tag so something like:

class TagItemModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = TagItem
        fields = '__all__'


class TagModelSerializer(serializers.ModelSerializer):
    items = serializers.SerializerMethodField()

    class Meta:
        model = Tag
        fields = '__all__'

    def get_items(self, obj):
        return TagItemModelSerializer(obj.tag_items.all(), many=True)

And in your views:

serializer = TagModelSerializer(Tags.objects.all(), many=True)
return Response(serializer.data)
Sign up to request clarification or add additional context in comments.

6 Comments

You can add depth = 1 at Meta instead of using serializers.SerializerMethodField()
Hi @bdbd, Gives a good path for nested serializers. But while implementing it give get_items() takes 1 positional argument but 2 were given. Should the function need no parameters?
Does this doc "django-rest-framework.org/api-guide/relations/…" be helpful? Or do you suggest some else?
Edited. Forgot to use self so it should be: def get_items(self, obj):
Also yes, thats the doc you can read to have more information about this.
|
0

I get unexpected keyword error when i tried to assign

1 Comment

Hi @Nik, With the error you shared, it looks like, the keyword passed during POST request is either incorrect or missing. Like "section" is entered as "sections" etc etc.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.