JSON API 与 Django Rest - 'included' 属性
JSON API with Django Rest - 'included' attribute
我正在使用 Django-rest 框架创建 JSON-API。除了 "included" 属性外,我可以按照 JSON-API 文档指定的方式构造 returned JSON 对象。有没有办法包含相关模型的多个序列化对象?
例如
如果我有两个模型类
# Snippet Model
from django.db import models
class Snippet(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
user = models.ForeignKey('auth.User', related_name='snippets')
# Comment Model
from django.db import models
class Comment(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
user = models.ForeignKey('auth.User', related_name='comments')
我有这两个模型的序列化程序:
from rest_framework import serializers
class SnippetSerializer(serializers.ModelSerializer):
model = Snippet
fields = ('id','created', 'title')
from rest_framework import serializers
class CommentSerializer(serializers.ModelSerializer):
model = Comment
fields = ('id','created', 'title')
我有用户序列化器
# User serializer
from .serializers import SnippetSerializer
from .serializers import CommentSerializer
class UserSerializer(serializers.ModelSerializer):
included = serializers.SerilizerMethodField()
class Meta:
model = User
fields = ('id','included')
def get_included(self, obj):
included_objs = []
request = self.context['request']
# check if requested url has a query parameter "included"
query = request.QUERY_PARAMS['included'] if 'included' in request.QUERY_PARAMS else None
if query:
queries = query.split(',')
if 'included' in queries:
snippets = SnippetSerializer(many=True, read_only=True).data
comments = CommentSerializer(many=True, read_only=True).data
included_objs.append(snippets)
included_objs.append(comments)
return included_objs
并且这些代码没有提供我需要的东西。
中的objective是如果请求url包含一个查询"included",那么API会return一个JSON带有CommentSerialized的对象'included' 属性下与用户对象相关的 SnippetSerialized 对象。结果应该是这样的。
{
"id" : 1,
"included": [
{'id': 2,'created': "20150729", "title":'snippet' },
{'id': 2,'created': "20150730", "title":"comment" },
{'id': 3,'created': "20150731", "title":"comment" },
]
}
如果有人能帮助我,那就太好了。谢谢!
为此,我将编写第二个序列化程序:
class IncludedUserSerializer(serializers.ModelSerializer):
snippets = SnippetSerializer(source = 'snippet_set', many=True)
comments = CommentSerializer(source = 'comment_set', many=True)
class Meta:
model=User
fields = ('id','snippets', 'comments')
然后在您的视图中覆盖 get_serializer 方法
def get_serializer(self):
if self.query_params.get('included', None):
return IncludedUserSerializer
else:
return UserSerializer
项目 django-rest-framework-json-api 最近实现了对此行为的支持。
它的用法是这样的:
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=200)
# PostSerializer NOT included directly on the serializer, ResourceRelatedField is
# specified as default
posts = relations.ResourceRelatedField(
source='post_set', many=True, read_only=True)
# specifies serializer to use when passing in the `include` param
included_serializers = {
'posts': PostSerializer,
}
如果我理解得很好,你已经自己实现了JSON-API规范的一部分,所以我不知道你是否可以切换并使用他们的项目。但是看看他们如何实现你想要的可能会有一些帮助。
例如,参见 this and this。
我正在使用 Django-rest 框架创建 JSON-API。除了 "included" 属性外,我可以按照 JSON-API 文档指定的方式构造 returned JSON 对象。有没有办法包含相关模型的多个序列化对象?
例如
如果我有两个模型类
# Snippet Model
from django.db import models
class Snippet(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
user = models.ForeignKey('auth.User', related_name='snippets')
# Comment Model
from django.db import models
class Comment(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
user = models.ForeignKey('auth.User', related_name='comments')
我有这两个模型的序列化程序:
from rest_framework import serializers
class SnippetSerializer(serializers.ModelSerializer):
model = Snippet
fields = ('id','created', 'title')
from rest_framework import serializers
class CommentSerializer(serializers.ModelSerializer):
model = Comment
fields = ('id','created', 'title')
我有用户序列化器
# User serializer
from .serializers import SnippetSerializer
from .serializers import CommentSerializer
class UserSerializer(serializers.ModelSerializer):
included = serializers.SerilizerMethodField()
class Meta:
model = User
fields = ('id','included')
def get_included(self, obj):
included_objs = []
request = self.context['request']
# check if requested url has a query parameter "included"
query = request.QUERY_PARAMS['included'] if 'included' in request.QUERY_PARAMS else None
if query:
queries = query.split(',')
if 'included' in queries:
snippets = SnippetSerializer(many=True, read_only=True).data
comments = CommentSerializer(many=True, read_only=True).data
included_objs.append(snippets)
included_objs.append(comments)
return included_objs
并且这些代码没有提供我需要的东西。
中的objective是如果请求url包含一个查询"included",那么API会return一个JSON带有CommentSerialized的对象'included' 属性下与用户对象相关的 SnippetSerialized 对象。结果应该是这样的。
{
"id" : 1,
"included": [
{'id': 2,'created': "20150729", "title":'snippet' },
{'id': 2,'created': "20150730", "title":"comment" },
{'id': 3,'created': "20150731", "title":"comment" },
]
}
如果有人能帮助我,那就太好了。谢谢!
为此,我将编写第二个序列化程序:
class IncludedUserSerializer(serializers.ModelSerializer):
snippets = SnippetSerializer(source = 'snippet_set', many=True)
comments = CommentSerializer(source = 'comment_set', many=True)
class Meta:
model=User
fields = ('id','snippets', 'comments')
然后在您的视图中覆盖 get_serializer 方法
def get_serializer(self):
if self.query_params.get('included', None):
return IncludedUserSerializer
else:
return UserSerializer
项目 django-rest-framework-json-api 最近实现了对此行为的支持。
它的用法是这样的:
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=200)
# PostSerializer NOT included directly on the serializer, ResourceRelatedField is
# specified as default
posts = relations.ResourceRelatedField(
source='post_set', many=True, read_only=True)
# specifies serializer to use when passing in the `include` param
included_serializers = {
'posts': PostSerializer,
}
如果我理解得很好,你已经自己实现了JSON-API规范的一部分,所以我不知道你是否可以切换并使用他们的项目。但是看看他们如何实现你想要的可能会有一些帮助。 例如,参见 this and this。