【问题标题】:Can't get Django Rest Framework GET vs POST structure to differ无法让 Django Rest Framework GET 与 POST 结构有所不同
【发布时间】:2016-10-27 04:56:47
【问题描述】:

我有一个看起来像这样的模型:

class Pet(models.Model):
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=200)
    primary_contact = models.ForeignKey(Person)

我的序列化器如下所示:

class PetSerializer(serializers.ModelSerializer):

    class Meta:
        model = Pet
        fields = ('id', 'name', 'description', 'primary_contact')

我的视图集:

class PetViewSet(viewsets.ModelViewSet):
    queryset = Pet.objects.all()
    serializer_class = PetSerializer

我的问题:

如果我在端点执行“GET”,我的结果如下所示:

[
  {
    "id": 1,
    "name": "Ripley",
    "description": "Black / Tan Yorkie",
    "primary_contact": 1
  }
]

primary_contact 只带回 Person 对象的 ID。这正是我希望 POSTing 结构的样子。当我发布时,我只想提供 Person 对象的 ID。但是,当我 GET 时,我希望内容看起来像这样:

[
  {
    "id": 1,
    "name": "Ripley",
    "description": "Black / Tan Yorkie",
    "primary_contact": {
        "id": 1,
        "first_name": "MyFistName",
        "last_name": "MyLastName",
        "phone": "312-xxx-xxxx",
        "email": "aarsan@abc123.com"
    }
  }
]

我可以通过在我的序列化程序中设置 depth=2 来获得上述结构,但是如果我尝试 POST,它会尝试创建 primary_contact,我不想这样做,因为它已经存在。

当我有外键时,我一直在使用的解决方法是为 POST 和 GET 创建不同的端点,我希望这不是唯一的方法。

【问题讨论】:

    标签: python json django serialization django-rest-framework


    【解决方案1】:

    你想要一个nested serializer。在这种情况下,您必须 define a serializer for primary contactlink in with primary contact field of PetSerializer

    class ContactSerializer(serializers.ModelSerializer):
        class Meta:
            model = Contact
            fields = ('id', 'field2', 'field3', '...')
    
    class PetSerializer(serializers.ModelSerializer):
        primary_contact = ContactSerializer()
        class Meta:
            model = Pet
            fields = ('id', 'name', 'description', 'primary_contact')
    

    【讨论】:

    • 谢谢,@cutteeth,但这似乎不起作用。它仍然尝试创建嵌套字段,当我设置 read_only=True 时,如果我尝试使用 primary_contact: 1 进行 POST,它会引发错误:“无法将值 NULL 插入列‘primary_contact_id’,表‘condoapp.dbo.condoapp_pet '; 列不允许空值。INSERT 失败”。
    • Django rest 框架有一个很好的 HTML 界面。检查引发错误的同一个 post 请求的 get 请求返回什么,并尝试以相同的格式发出 post 请求。
    • 谢谢。这正是我进行测试的方式以及我发现它不起作用的方式。
    • 另外,正如我在原始问题中提到的,我不想发布与“GET”相同的数据。我希望 GET 包含有关 primary_contact 的详细信息,并且我希望 POST 仅具有 primary_contact ID。
    【解决方案2】:

    您可以在同一个 ViewSet 中拥有多个序列化程序,为此您需要覆盖 get_serializer_classmethod。

    看看这个:http://www.django-rest-framework.org/api-guide/generic-views/#get_serializer_classself

    【讨论】:

      猜你喜欢
      • 2018-12-22
      • 2013-03-30
      • 2020-04-15
      • 2014-10-03
      • 2018-03-06
      • 1970-01-01
      • 2012-09-07
      • 1970-01-01
      • 2019-02-12
      相关资源
      最近更新 更多