You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF中能否通过SlugRelatedField实现Word模型的正向查询?

DRF序列化问题:能否用SlugRelatedField获取Word模型完整信息?

期望输出格式

slides = [
  {
    "id": "1",
    "sentence": "The person is in the house.",
    "sentence-type": "simple",
    "clauses": {
      "type": "independent clause",
      "description": "An independent clause has a subject and a verb. An independent clause expresses a complete thought."
    },
    "wordlist": [
      {
        "pos": "article",
        "pos_description": "An article modifies a noun like an adjective does and are considered necessary to provide proper syntax to a sentence.",
        "colour": "21 128 61",
        "word": "the"
      }
    ]
  }
]

现有模型定义

class Sentence(models.Model):
   sentence = models.CharField(max_length=500)
   # 注:实际需补充sentence_type字段以匹配输出需求
class Word(models.Model):
    word = models.CharField(max_length=255)
    part_of_sentence = models.ForeignKey(PartOfSentence, related_name='pos_word', on_delete=models.CASCADE, blank=True, null=True)
    words = models.ForeignKey(Sentence, related_name='sentence_word', on_delete=models.CASCADE, blank=True, null=True)
class PartOfSentence(models.Model):
    part_of_sentence = models.CharField(max_length=20)
    pos_colour = models.CharField(max_length=20)
    pos_description = models.CharField(max_length=512)
class Clause(models.Model):
    TYPES = (
        ('NONE', 'None'),
        ('INDEPENDENT', 'Independent'),
        ('DEPENDENT', 'Dependent'),
        ('COORDINATING_CONJUNCTION', 'Coordinating-Conjunction'),
        ('SUBORDINATING_CONJUNCTION', 'Subordinating-Conjunction')
    )
    clause = models.CharField(choices=TYPES, max_length=40, default='None')

当前序列化器定义

class ClauseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Clause
        fields = ('clause',)
class SentenceSerializer(serializers.ModelSerializer):
    clause = ClauseSerializer()
    words = serializers.SlugRelatedField(
        source='sentence_word',
        slug_field='word',
        many=True,
        read_only=True
    )

    class Meta:
        model = Sentence
        fields = ('sentence', 'sentence_type', 'clause', 'words')

当前序列化输出

[
    {
        "sentence": "the person is in the house",
        "sentence_type": "SIMPLE",
        "clause": {
            "clause": "INDEPENDENT",
            "description": "An independent clause has a subject and a verb. An independent clause expresses a complete thought"
        },
        "words": [
            "the",
            "person",
            "is"
        ]
    }
]

问题

当前输出的words数组仅包含单词字符串,缺少词性(pos)、词性描述(pos_description)、颜色(colour)等关键信息,咨询是否可以通过SlugRelatedField实现Word模型的正向查询,以获取完整的单词相关结构。


解答

不能用SlugRelatedField实现这个需求。SlugRelatedField的核心作用是序列化出关联模型的单个字段值(比如仅返回word字段的字符串),无法生成包含多字段的对象结构。要获取Word模型及关联PartOfSentence的完整信息,必须使用嵌套序列化器,具体修改步骤如下:

1. 编写PartOfSentence序列化器

用于序列化词性相关的描述和颜色字段:

class PartOfSentenceSerializer(serializers.ModelSerializer):
    class Meta:
        model = PartOfSentence
        fields = ('part_of_sentence', 'pos_description', 'pos_colour')

2. 编写Word序列化器

映射期望输出的字段名,同时关联PartOfSentence的信息:

class WordSerializer(serializers.ModelSerializer):
    # 映射字段名以匹配期望输出
    pos = serializers.CharField(source='part_of_sentence.part_of_sentence')
    pos_description = serializers.CharField(source='part_of_sentence.pos_description')
    colour = serializers.CharField(source='part_of_sentence.pos_colour')

    class Meta:
        model = Word
        fields = ('word', 'pos', 'pos_description', 'colour')

3. 修改Sentence序列化器

替换SlugRelatedField为WordSerializer,并调整字段名匹配期望输出:

class ClauseSerializer(serializers.ModelSerializer):
    # 调整Clause序列化器以匹配期望的输出结构
    type = serializers.SerializerMethodField()
    description = serializers.SerializerMethodField()

    def get_type(self, obj):
        # 将choices值转换为友好名称,比如INDEPENDENT转为"independent clause"
        if obj.clause == 'INDEPENDENT':
            return "independent clause"
        # 可补充其他类型的转换逻辑
        return obj.get_clause_display().lower()

    def get_description(self, obj):
        # 返回对应从句类型的描述文本
        if obj.clause == 'INDEPENDENT':
            return "An independent clause has a subject and a verb. An independent clause expresses a complete thought."
        return ""

    class Meta:
        model = Clause
        fields = ('type', 'description')

class SentenceSerializer(serializers.ModelSerializer):
    clauses = ClauseSerializer()  # 字段名改为clauses匹配期望输出
    wordlist = WordSerializer(source='sentence_word', many=True, read_only=True)  # 替换SlugRelatedField为嵌套序列化器

    class Meta:
        model = Sentence
        fields = ('id', 'sentence', 'sentence_type', 'clauses', 'wordlist')  # 加入id字段,调整字段名匹配期望输出

关键说明

  • SlugRelatedField仅适用于需要返回单个字段值的场景,无法满足多字段对象的序列化需求;
  • 嵌套序列化器可以完整序列化关联模型的所有需要的字段,包括跨模型关联的信息(比如Word关联的PartOfSentence数据);
  • 通过source参数可以灵活映射模型字段到输出的字段名,确保和期望格式一致。

内容的提问来源于stack exchange,提问作者miriad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:25:18