GenericRelatedObjectManager不是JSON可序列化的

时间:2015-04-30 17:33:17

标签: python django django-rest-framework

我正在使用Django REST Framework,我正在尝试创建一个通用关系。当我尝试查看DeviceModel时,它会抛出错误

<django.contrib.contenttypes.fields.GenericRelatedObjectManager object at 0x2b7e6d0> is not JSON serializable

文档明确指出反向通用关系应该有效,所以我做错了什么?

我的模特:

class GenericDevice(models.Model):
    #other fields...
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    device_model = GenericForeignKey('content_type', 'object_id')

class DeviceModel(models.Model):
    #other fields...
    generic_model = GenericRelation(GenericDevice)

串行器:

class DeviceModelSerializer(serializers.ModelSerializer):

    generic_model = serializers.PrimaryKeyRelatedField(
        queryset = models.GenericDevice.objects.all()
    )

    class Meta:
        model = models.SSDDeviceModel
        fields = (...other fields..., 'generic_model')

class DeviceModelRelatedField(serializers.PrimaryKeyRelatedField):
    def to_representation(self, value):
        if isinstance(value, models.DeviceModel):
            serializer = DeviceModelSerializer(value)
        else:
            raise Exception('Unexpected device model')
        return serializer.data

class GenericDeviceSerializer(serializers.ModelSerializer):
    device_model = DeviceModelRelatedField(queryset=models.DeviceModel.objects.all())

    class Meta:
        model = models.GenericDevice
        fields = ('device_model')

1 个答案:

答案 0 :(得分:2)

我刚刚遇到这个问题。我想我用以下代码解决了它,松散地模仿了Django REST docs - Generic Relationships

(我希望它有所帮助。我是Django的新手。如果我能让它变得更优雅,我会更新它。)

我的模特:

from django.contrib.auth.models import User
from django.db import models
from django_extensions.db.models import TimeStampedModel
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType


class TaggedItem(models.Model):
    """
    Tags arbitrary model instances using a generic relation.
    """
    tag_name = models.SlugField()
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    tagged_object = GenericForeignKey('content_type', 'object_id')
    user_created = models.BooleanField(default=True)

    class Meta:
        verbose_name = 'tag'
        verbose_name_plural = 'tags'

    def __str__(self):
        return self.tag_name 


class Bookmark(TimeStampedModel):
    """
    A bookmark consists of a URL, and 0 or more descriptive tags.
    """
    user = models.ForeignKey(User, verbose_name='user', related_name='bookmarks')
    url = models.URLField()
    title = models.CharField('title', max_length=255)
    description = models.TextField('description', blank=True)
    tags = GenericRelation(TaggedItem)

    class Meta:
        unique_together = ("url", "user")
        verbose_name = 'bookmark'
        verbose_name_plural = 'bookmarks'

    def __str__(self):
        return '%s (%s)' % (self.title, self.user)

我的序列化程序:

# 3rd Party
from rest_framework import serializers
from rest_framework.pagination import PageNumberPagination

# Market Builder
from market_builder.serializers import HATEOASMixin
from . import models


class BookmarkPagination(PageNumberPagination):
    """Bookmark pagination serialization."""

    page_size = 10
    page_size_query_param = 'page_size'


class TaggedObjectRelatedField(serializers.RelatedField):
    """
    Serialize bookmark instances using a bookmark serializer.
    """

    def to_representation(self, value):
        if isinstance(value, models.Bookmark):
            serializer = BookmarkSerializer(value)
        else:
            raise Exception('Unexcepted type of tagged object')

        return serializer.data


class TaggedItemSerializer(serializers.ModelSerializer):
    """Tagged Item serialization."""

    class Meta:
        model = models.TaggedItem
        fields = [
            'tag_name',
            'user_created',
            'object_id',
        ]


class BookmarkSerializer(HATEOASMixin, serializers.ModelSerializer):
    """Bookmark serialization."""

    links = serializers.SerializerMethodField()
    tags = TaggedItemSerializer(many=True)

    class Meta:
        model = models.Bookmark
        fields = [
            'id',
            'url',
            'title',
            'description',
            'created',
            'modified',
            'tags',
            'links',
        ]

    def get_links(self, bookmark):
        links = super().get_links(bookmark)
        return links

我的管理员

from django.contrib import admin
from django.contrib.contenttypes import admin as cadmin

from .models import Bookmark, TaggedItem


class TaggedItemInline(cadmin.GenericTabularInline):
    model = TaggedItem


class BookmarkAdmin(admin.ModelAdmin):
    list_display = ('title', 'url', 'user', )
    list_filter = ('user', )
    search_fields = ['url', 'title']
    inlines = [
        TaggedItemInline,
    ]


class TaggedItemAdmin(admin.ModelAdmin):
    list_display = ('tag_name', )

admin.site.register(Bookmark, BookmarkAdmin)
admin.site.register(TaggedItem, TaggedItemAdmin)