Python中drf的onetoonefield在ModelSerializer中该如何定义?

比如:
class Engine(models.Model):
name = models.CharField(max_length=25)



class Car(models.Model):
name = models.CharField(max_length=25)
engine = models.OneToOneField(Engine)


我想创建一个 car 的时候同时创建一个 engine,这样的 ModelSerializer 该怎样写?
Python中drf的onetoonefield在ModelSerializer中该如何定义?


4 回复

重写一个 Car 的 save 就行了啊


在DRF的ModelSerializer中定义OneToOneField,直接使用字段名就行,ModelSerializer会自动处理。

比如你有两个模型,UserProfile,通过OneToOneField关联:

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=100)

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    bio = models.TextField()

Profile创建ModelSerializer时,user字段会自动被映射为一个PrimaryKeyRelatedField,用于接收或输出关联User的主键:

from rest_framework import serializers
from .models import Profile

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ['id', 'user', 'bio'] # 这里直接包含'user'字段

如果你想在序列化输出时嵌套展示关联对象的信息(比如在获取Profile时直接看到User的详情),而不是只显示一个用户ID,你需要重写这个字段。通常有两种方式:

  1. 使用嵌套序列化器(更常用):创建一个UserSerializer,然后在ProfileSerializer中将其用作user字段。

    from rest_framework import serializers
    from .models import User, Profile
    
    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ['id', 'username']
    
    class ProfileSerializer(serializers.ModelSerializer):
        # 将user字段指定为嵌套的UserSerializer
        user = UserSerializer(read_only=True) # 通常GET请求时设为只读
    
        class Meta:
            model = Profile
            fields = ['id', 'user', 'bio']
    

    这样,GET请求返回的数据格式会是:

    {
        "id": 1,
        "user": {
            "id": 1,
            "username": "john_doe"
        },
        "bio": "A developer."
    }
    
  2. 使用source参数:如果你想在Profile的序列化器中展示User的某个特定字段(比如用户名),也可以这样写:

    class ProfileSerializer(serializers.ModelSerializer):
        username = serializers.CharField(source='user.username', read_only=True)
    
        class Meta:
            model = Profile
            fields = ['id', 'user', 'username', 'bio']
    

关键点总结

  • 默认情况ModelSerializer会自动为OneToOneField生成基于主键的字段。
  • 需要嵌套数据:手动将字段定义为关联模型的序列化器(如user = UserSerializer())。
  • 写操作注意:如果使用了嵌套序列化器(UserSerializer),默认情况下它可能不支持直接创建或更新关联的User对象。对于复杂的写入逻辑(如通过Profile创建User),你需要在视图或序列化器的createupdate方法中自定义处理。

一句话建议:要嵌套展示就用嵌套序列化器,只关联ID就用默认。

新建模型类重写 ModelSerializer 中的 create 方法,更新模型类重写 update 方法

采用了这个方法,谢谢

回到顶部