如何在Django中序列化外键休息?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Django中序列化外键休息?相关的知识,希望对你有一定的参考价值。

我正在使用最新版本的django rest框架。

我有这个型号:

class Subscriptions(models.Model):

subs_list = models.ForeignKey(SubsList, verbose_name='Subscription list', on_delete=models.CASCADE,  related_name='subs_list')  # идентификатор подписного листа
subscriber = models.ForeignKey(Subscribers, verbose_name='Subscriber', on_delete=models.CASCADE)  # идентификатор подписчика
created_date = models.DateTimeField(verbose_name='Created date', auto_now=True)  # дата добавления подписчика в подписной лист
deleted = models.NullBooleanField(verbose_name='Deleted')  # True-удален из подписного листа, False/null-в подписном листе

我该如何序列化?主要问题是如何序列化ForeignKey,它将与查询相关的数据相关联,即NOT:

"id": 29,
  "created_date": "2018-03-01T14:28:41.237742Z",
  "deleted": false,
  "subs_list": 1,
  "subscriber": 1

但是像这样

"id": 29,
  "subs_list": {
    "id": 1,
    "uuid": "d183bab7-af26-48f8-9ef5-ea48e09a95a9",
    "name": "TEST",
    "description": "TEST",
    "created_date": "2018-03-01T13:15:18.808709Z",
    "deleted": null,
    "user": 6
  },
  "subscriber": {
    "id": 1,
    "bot_id": "1",
    "name_messenger": "11",
    "username": "1",
    "first_name": "1",
    "last_name": "1",
    "created_date": "9999-03-01T16:47:51.440000Z",
    "subscribed": true,
    "chat_bot": "1",
    "phone": "1",
    "user": 1
  },
  "created_date": "2018-03-01T14:28:41.237742Z",
  "deleted": false

我有这样的序列化器:

...
class SubscriptionsSerializer(serializers.ModelSerializer):
subs_list = SubsListSerializer(read_only=True)
subscriber = SubscribersSerializer(read_only=True)

class Meta:
    model = Subscriptions
    fields = '__all__'

获取请求时一切正常,但如何更新和添加数据尚不清楚,错误:/ subsptions / subscriptions / null列中的“subs_list_id”中的IntegrityError违反非空约束DETAIL:失败行包含(41,2018-03) -01 16:10:02.383625 + 00,f,null,null)。

我很长时间都在努力解决这个问题,阅读所有相关的答案,但是没有明确的。

答案

删除read_only=True并更改您的serializer.py如下

class SubscriptionsSerializer(serializers.ModelSerializer):
    subs_list = SubsListSerializer()
    subscriber = SubscribersSerializer()

    class Meta:
        model = Subscriptions
        fields = '__all__'

    def create(self, validated_data):
        sub_lst = SubsList.objects.create(**validated_data['subs_list'])
        subscriber = Subscribers.objects.create(**validated_data['subscriber'])
        return Subscriptions.objects.create(subs_list=sub_lst, subscriber=subscriber, deleted=validated_data['deleted'])

而你的creation payload将是这样的,

{
    "subs_list": {
         "uuid": "d183bab7-af26-48f8-9ef5-ea48e09a95a9",
         "name": "TEST",
         "description": "TEST",
         # etc etc
         },
    "subscriber": {
                "bot_id": "1",
                "name_messenger": "11",
                "username": "1",
                # etc etc
            },

            "deleted": null
        }

我认为你有几个ForeignKey关系,所以你必须在create()仔细地映射这些东西 类似地,您可以覆盖update(),也可以在API更新时使用。 有关更多信息,请参阅this official doc

以上是关于如何在Django中序列化外键休息?的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest Framework:具有通用外键的可写嵌套序列化程序

当父记录存在时,如何在 django rest 框架的子序列化程序中设置外键值

在 Django 中序列化外键对象

带有嵌套序列化程序的 Django 反向外键给出了多个结果

在序列化程序中编辑外键字段 - Django Rest Framework

oTree 中的 Django 休息框架