2013-02-20 61 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

相關問題