9

使用Django 休息

下面是我的 serializer.py 的方式。

class ProfileSerializer(serializers.ModelSerializer):


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

类型是平面视图

然后我对其进行了更改,因此像这样为每个配置文件嵌套了“类型”...

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'')

现在这很完美,但我现在只能在配置文件详细信息中更新“类型”,它现在是只读的。

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

我希望我已经解释清楚了。

更新:

好的,我刚读到这个:

注意:嵌套序列化程序仅适用于只读表示,因为在某些情况下,如果在更新实例时使用它们会产生模棱两可或不明显的行为。对于读写表示,您应该始终通过使用相关字段子类之一来使用平面表示。

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

type = serializers.PrimaryKeyRelatedField()

这让它回到 POST 并工作,但很遗憾,我不能用 ID 和名称表示“类型”,这样对最终用户更有意义吗?

4

3 回答 3

13

对可写嵌套序列化程序的完全支持是一项正在进行的工作,但同时一种解决方案是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)

可能并不理想,但它对我有用,直到出现正确的方法。

于 2013-02-20T11:50:05.320 回答
6

我在 django-rest-framework 中遇到了同样的问题,并且我创建了一个视图来快速执行此操作,您可以在以下要点中找到它:https ://gist.github.com/edulix/5311365

CRUDManyToManyView的基本用法如下:

视图.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

网址.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')

模型.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 projects/12/tasks/将列出项目任务
  • POST projects/12/tasks/1/这会将任务 1 添加到项目 12 任务列表中(任务 1 必须已经存在)
  • DELETE projects/12/tasks/1/将从项目 12 任务列表中删除任务 1
于 2013-04-04T15:36:49.690 回答
5

现在支持这一点(我使用的是 2.3.6 版,但它可能会更早引入)。您可以像这样在序列化程序中直接使用它:

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

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

    class Meta:
        model = Album

希望能帮助到你 :)

于 2013-07-01T19:04:07.473 回答