DRF:使用嵌套序列化程序的简单外键分配?

2022-01-31 00:00:00 python django django-rest-framework

问题描述

使用 Django REST 框架,标准 ModelSerializer 将允许通过将 ID 作为整数发布来分配或更改 ForeignKey 模型关系.

With Django REST Framework, a standard ModelSerializer will allow ForeignKey model relationships to be assigned or changed by POSTing an ID as an Integer.

从嵌套序列化程序中获得这种行为的最简单方法是什么?

What's the simplest way to get this behavior out of a nested serializer?

注意,我只是在谈论分配现有的数据库对象,不是嵌套创建.

Note, I am only talking about assigning existing database objects, not nested creation.

我过去在序列化程序中使用额外的id"字段以及自定义 createupdate 方法解决了这个问题,但这看起来很简单我很想知道最好的方法.

I have hacked away around this in the past with additional 'id' fields in the serializer and with custom create and update methods, but this is such a seemingly simple and frequent issue for me that I'm curious to know the best way.

class Child(models.Model):
    name = CharField(max_length=20)

class Parent(models.Model):
    name = CharField(max_length=20)
    phone_number = models.ForeignKey(PhoneNumber)
    child = models.ForeignKey(Child)

class ChildSerializer(ModelSerializer):
    class Meta:
        model = Child

class ParentSerializer(ModelSerializer):
    # phone_number relation is automatic and will accept ID integers
    children = ChildSerializer() # this one will not

    class Meta:
        model = Parent


解决方案

这里最好的解决方案是使用两个不同的字段:一个用于读取,另一个用于写入.如果不做一些繁重的工作,就很难在单个字段中获得你想要的东西.

The best solution here is to use two different fields: one for reading and the other for writing. Without doing some heavy lifting, it is difficult to get what you are looking for in a single field.

只读字段将是您的嵌套序列化程序(在本例中为 ChildSerializer),它将允许您获得与您期望的相同的嵌套表示.大多数人将其定义为child,因为他们的前端已经写好了,改变它会导致问题.

The read-only field would be your nested serializer (ChildSerializer in this case) and it will allow you to get the same nested representation that you are expecting. Most people define this as just child, because they already have their front-end written by this point and changing it would cause problems.

只写字段将是 PrimaryKeyRelatedField,这是您通常用于根据主键分配对象的方法.这不一定是只写的,特别是如果您试图在接收和发送的内容之间实现对称,但听起来这可能最适合您.该字段应将 a source 设置为外部关键字段(本例中为 child),以便在创建和更新时正确分配它.

The write-only field would be a PrimaryKeyRelatedField, which is what you would typically use for assigning objects based on their primary key. This does not have to be write-only, especially if you are trying to go for symmetry between what is received and what is sent, but it sounds like that might suit you best. This field should have a source set to the foreign key field (child in this example) so it assigns it properly on creation and updating.

这已经在讨论组中提出过几次了,我认为这仍然是最好的解决方案.感谢 Sven Maurer 指出.

This has been brought up on the discussion group a few times, and I think this is still the best solution. Thanks to Sven Maurer for pointing it out.

相关文章