简体   繁体   中英

How do I write a django-rest-framework serializer to save a nested hierarchy containing a generic model?

I am using django 1.6 and django-rest-framework 2.4. I have a generic model that has a foreign key relationship to another model. The generic model can obviously be associated with any other host model. I want to be able to save the host model and the generic model with all its associations in one go.

For example:

models.py:

from django.db import models
from django.contrib.contenttypes.generic import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType


class GenericItem(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    details = models.TextField(blank=True)


class GenericSubItem(models.Model):
    generic_item = models.ForeignKey(GenericItem, null=True, blank=True, related_name="sub_items")

    details = models.TextField(blank=True)


class Host(models.Model):
    details = models.TextField(blank=True)

    generic_items = GenericRelation(GenericItem, content_type_field='content_type', object_id_field='object_id')

serializers.py:

from rest_framework import serializers
from . import models


class GenericSubItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.GenericSubItem
        fields = ('id', 'details', )


class GenericItemSerializer(serializers.ModelSerializer):
    sub_items = GenericSubItemSerializer(many=True, required=False, allow_add_remove=True)

    class Meta:
        model = models.GenericItem
        fields = ('id', 'details', 'sub_items', )


class HostSerializer(serializers.ModelSerializer):
    generic_items = GenericItemSerializer(many=True, required=False, allow_add_remove=True)

    class Meta:
        model = models.Host
        fields = ('id', 'details', 'generic_items', )

views.py:

from rest_framework import viewsets
from . import serializers, models


class HostView(viewsets.ModelViewSet):
    queryset = models.Host.objects.all()
    serializer_class = serializers.HostSerializer

The problem here is that the sub_items don't get saved, even though they are posted. Even worse, if you add a sub item through the shell, it will display it fine but when you save, the sub item is deleted.

How should the serializer be written so that saving the host will save everything else?

Thanks,

Paul

Could you please give more details about your views.py ? Or you can have a try to override your create(self, validated_data) in your GenericItemSerializer as follow:

class GenericItemSerializer(serializers.ModelSerializer):
    sub_items = GenericSubItemSerializer(many=True, required=False, allow_add_remove=True)

    class Meta:
        model = models.GenericItem
        fields = ('id', 'details', 'sub_items', )

    def create(self, validate_data):
        subitemdata = validate_data.pop('sub_items')
        subitemobj = GenericSubItem.objects.create(**subitemdata)
        GenericItem.objects.create(sub_items=subitemobj, **validate_data)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM