2013-02-20 62 views
9

使用Django restDjango的REST:嵌套的对象添加上创建(POST)不只是更新(PUT)

下面是我怎么了我的serializer.py。

class ProfileSerializer(serializers.ModelSerializer): 


    class Meta: 
     model = Profile 
     fields = ('id', 'name', 'active', 'type') 

类型是flatview

我后又改之以“型”是嵌套像这样每个配置文件...

class TypeSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Type 
     fields = ('id', 'name', 'active') 

class ProfileSerializer(serializers.ModelSerializer): 

    type = TypeSerializer() 

    class Meta: 
     model = Profile 
     fields = ('id', 'name', 'active', 'type'') 

现在这个完美的作品,但我可以现在只在配置文件中更新“类型”,现在只读。

如何在创建新配置文件时添加类型并仍保留此嵌套视图?

我希望我已经解释清楚。

UPDATE:

好吧,我刚刚看了这样的:

注:嵌套的序列化只适用于只读 表示,因为有在那里他们将有模棱两可或 案件如果在更新实例时使用了非显而易见的行为。对于读写 表示法,您应始终使用平面表示法,方法是使用 之一的RelatedField子类。

所以这是有道理的。所以我改成了....

type = serializers.PrimaryKeyRelatedField() 

这使它回到POST和工作,但它是一个耻辱,所以它更有意义的我不能代表ID为“类型”和名称最终用户?

回答

12

写嵌套的序列化的全面支持是work in progress,但在此时间一个解决方案是重写create方法在每种情况下的视图:

class FooListCreateView(ListCreateAPIView): 
    model = Foo 
    serializer_class = FooSerializer 

    def create(self, request, *args, **kwargs): 
     data=request.DATA 

     f = Foo.objects.create() 

     # ... create nested objects from request data ... 

     # ... 
     return Response(serializer.data, 
         status=status.HTTP_201_CREATED, 
         headers=headers) 

可能不理想,但它为我工作直到适当的方式出现。

+0

我发现SlugRelatedField允许我现在从ID更改为有意义的像场,但多数民众赞成在标题或名称使用平面不嵌套。我会嵌套重试,看看覆盖是否可以工作。 – jason 2013-02-20 11:53:38

+0

你能解释一下,我们如何验证这里的其他领域? – CrazyGeek 2015-02-03 12:39:26

6

我在Django的REST的框架同样的问题,我已经创造了这样一个视图真正的快,你可以找到它在这个要点:https://gist.github.com/edulix/5311365

CRUDManyToManyView的基本用法如下:

views.py

from models import Project 
from serializers import TaskSerializer 
from lib.crudmanytomanyview import CRUDManyToManyView 

class ProjectTasks(CRUDManyToManyView): 
    model = Project 
    field_name = 'tasks' 
    serializer_class = TaskSerializer 

urls.py

from django.conf.urls import patterns, url 
import views 

urlpatterns = patterns(
'', 
    url(r'^projects/(?P<pk>[0-9]+)/tasks/((?P<field_pk>[0-9]+)/)?$', 
     views.ProjectTasks.as_view()), 
) 

序列化器。PY

from rest_framework import serializers 
from models import Task 

class TaskSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Task 
     fields = ('id', 'name') 

models.py

from django.db import models 

class Task(models.Model): 
    name = models.CharField(max_length=140, blank=False, null=False) 

class Project(models.Model): 
    name = models.CharField(max_length=140, blank=False, null=False) 
    tasks = models.ManyToManyField(Task, related_name='projects') 

然后,你可以做这样的事情:

  • GET项目/ 12 /任务/将列出项目任务
  • POST项目/ 12 /任务/ 1/将任务1增加的项目12个任务的列表(任务1必须已经存在)
  • DELETE项目/ 12 /任务/ 1/将从项目12个任务列表中删除任务1
4

现在支持(我正在使用2.3.6版本,但可能会早些介绍)。您可以在串行direcly这样使用它:

class SongSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Song 

class AlbumSerializer(serializers.ModelSerializer): 
    songs = SongSerializer(many=True) 

    class Meta: 
     model = Album 

希望它能帮助:)

+1

这段代码片段正确吗? ImageFeatureSerializer从哪里来? SongSerializer的模型是另一个SongSerializer? – user798719 2013-12-05 22:06:53

+0

对不起,我正在转换一些我自己的代码来适应上面的例子,并且有点急。这应该工作。谢谢! – 2013-12-06 08:54:29

+0

@RaresMusina POST请求现在会是什么样子? – 2017-07-07 19:18:59

相关问题