【问题标题】:Django RF Writable Nested SerializersDjango RF 可写嵌套序列化器
【发布时间】:2017-10-04 13:02:55
【问题描述】:

我正在尝试在 DRF3 中创建一个可写的嵌套序列化程序。 我的用户模型有一个带有 m2m 字段“技术人员”的模型 Concert。 我已在其视图中成功添加了连接到 Concert 实例的用户列表。现在我希望能够将技术人员/用户添加到 Concert 模型中。

到目前为止,这是我的序列化程序:

class ConcertListSerializer(serializers.ModelSerializer):
    technicians = UserDetailSerializer(
            many=True,
            read_only=True
        )

    class Meta:
        model = models.Concert
        fields = [
            'name',
            'date',
            'technicians',
            'id',
        ]

    def create(self, validated_data):
        # list of pk's
        technicians_data = validated_data.pop('technicians')
        concert = Concert.object.create(**validated_data)

        for tech in technicians_data:
            tech, created = User.objects.get(id = tech) 
            concert.technicians.add({
                    "name": str(tech.name),
                    "email": str(tech.email),
                    "is_staff": tech.is_staff,
                    "is_admin": tech.is_admin,
                    "is_superuser": tech.is_superuser,
                    "groups": tech.groups,
                    "id": tech.id
                })
        return concert

我希望能够只添加我想要添加的技术人员的 pk/id 列表。比如:

"technicians": [1,2,3]

将用户 1、2、3 添加到 Concert 的技术人员字段。

每当我这样做时,我都会得到 KeyError,它只是说“技术人员”并引用我的 create() 函数中的第一行...

我在字典中添加的字段是用户模型的所有字段。这是我执行 GET 请求时显示的格式。

这是 Concert 模型:

class Concert(models.Model):
    name = models.CharField(max_length=255)
    date = models.DateTimeField(default =
                                datetime.now(pytz.timezone('Europe/Oslo'))
                                + timedelta(days=30)
                            )
    technicians = models.ManyToManyField(User)  # relation to user model

编辑: 这是对预制示例音乐会的 GET 请求的响应:

{
    "name": "Concert-name",
    "date": "2017-10-28T12:11:26.180000Z",
    "technicians": [
        {
            "name": "",
            "email": "test2@test.com",
            "is_staff": true,
            "is_admin": true,
            "is_superuser": false,
            "groups": [
                5
            ],
            "id": 2
        },
        {
            "name": "",
            "email": "test3@test.com",
            "is_staff": true,
            "is_admin": true,
            "is_superuser": false,
            "groups": [
                5
            ],
            "id": 3
        }
    ],
    "id": 1
}

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    您应该从上下文请求中获取数据,因为您提交的文件是只读的,validated_data 中缺少它

    def create(self, validated_data):
        # list of pk's
        # instaed of technicians_data = validated_data.pop('technicians')
        # use next two lines
        request = self.context.get('request')
        technicians_data = request.data.get('technicians')
    
        concert = Concert.object.create(**validated_data)
    
        # Added technicians
        for tech in technicians_data:
            user = User.objects.get(id=tech) 
            concert.technicians.add(user)
    
        return concert
    

    【讨论】:

    • 我会试一试,但 DRF 文档说要像我一样做:django-rest-framework.org/api-guide/relations/…
    • 我添加了说明为什么你可以使用它。
    • 我应该给 Concert.object.create() 哪些参数?
    • 好吧,我删除了只读,现在我得到了数据。现在的问题是 django 期望在 POST 请求中获得完整的用户字典。我收到 NoneField 错误。如何让 Django 接受 ID 列表,然后让我的 create() 方法构造字典?
    • 您需要返回read_only,然后在我写答案时从请求中获取数据
    猜你喜欢
    • 2015-03-20
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    相关资源
    最近更新 更多