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

如何在Django Rest Framework中设计食材ArrayField及对应序列化方法

解决方案

一、模型层字段定义

分两种实现方案,可根据业务需求选择:

方案1:JSONField直接存储(无单独食材管理需求优先选)

如果不需要对食材做独立的查询、统计、复用操作,直接用Django原生JSONField存储即可,代码最简:

from django.db import models

class Meal(models.Model):
    name = models.TextField()    
    recipe = models.TextField()
    # 直接存储嵌套数组结构,默认值设为空数组
    ingredients = models.JSONField(default=list)

注:Django 3.1及以上版本原生支持JSONField,兼容PostgreSQL、MySQL、SQLite等主流数据库,会自动完成Python数据类型和数据库JSON格式的双向转换。

写入数据的示例:

Meal.objects.create(
    name="spaghetti",
    recipe="recipe",
    ingredients=[
        [{"name":"pasta", "amount":100}, {"name":"tomato", "amount":200}]
    ]
)

方案2:关联独立Ingredient模型(需要食材统一管理优先选)

如果后续需要统计食材使用频次、复用食材基础信息等,建议拆分独立模型做关联:

from django.db import models

class Meal(models.Model):
    name = models.TextField()    
    recipe = models.TextField()

# 食材独立模型
class Ingredient(models.Model):
    name = models.TextField()
    amount = models.IntegerField()
    # 分组字段:用来匹配你需要的内层数组分组逻辑,没有分组需求可以删除
    group = models.IntegerField(default=0)
    meal = models.ForeignKey(Meal, on_delete=models.CASCADE, related_name="ingredients")

二、序列化逻辑实现

和上面的两种方案一一对应:

对应方案1的序列化

不需要额外自定义逻辑,直接声明字段即可:

from rest_framework import serializers
from .models import Meal

class MealSerializer(serializers.ModelSerializer):
    class Meta:
        model = Meal
        fields = ["id", "name", "recipe", "ingredients"]

序列化后返回的结构和你存储的结构完全一致,直接匹配你给出的JSON格式要求。

对应方案2的序列化

需要自定义字段逻辑,把关联的食材对象按分组组装为嵌套数组:

from rest_framework import serializers
from .models import Meal, Ingredient

class IngredientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Ingredient
        fields = ["name", "amount"]

class MealSerializer(serializers.ModelSerializer):
    ingredients = serializers.SerializerMethodField()

    def get_ingredients(self, obj):
        # 按group字段分组
        groups = {}
        for ing in obj.ingredients.all().order_by("group", "id"):
            groups.setdefault(ing.group, []).append(IngredientSerializer(ing).data)
        # 转换为嵌套数组返回
        return list(groups.values())

    class Meta:
        model = Meal
        fields = ["id", "name", "recipe", "ingredients"]

注:如果你给出的JSON中两层数组是笔误,只需要单层数组的话,直接把ingredients字段声明为ingredients = IngredientSerializer(many=True)即可,不需要自定义get_ingredients方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:36:03