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

如何使用django-import-export导出带嵌套关联关系的JSON数据

django-import-export 嵌套关联JSON导出导入实现方案

核心思路

通过自定义ModelResource的字段脱水方法生成嵌套结构,同时重写实例保存前置方法实现嵌套数据的解析导入,完全适配跨环境数据同步的需求。


1. 参考示例模型定义(对应官方Book/Author/Category场景)

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

class Category(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    name = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="books")
    categories = models.ManyToManyField(Category, related_name="books")
    imported = models.BooleanField(default=False)

2. 自定义资源类实现嵌套导出

from import_export import resources, fields
from .models import Book, Author, Category

class BookResource(resources.ModelResource):
    # 显式声明嵌套字段
    Author = fields.Field(attribute="author")
    categories = fields.Field(attribute="categories")

    class Meta:
        model = Book
        fields = ("name", "Author", "categories", "imported")

    # 脱水方法处理外键字段,返回嵌套字典
    def dehydrate_Author(self, book):
        return {"name": book.author.name}

    # 脱水方法处理多对多字段,返回嵌套字典列表
    def dehydrate_categories(self, book):
        return [{"name": cat.name} for cat in book.categories.all()]

3. 导出调用示例

# 导出全量书籍数据为JSON
dataset = BookResource().export()
json_data = dataset.json
# 直接输出json_data即可得到你需要的嵌套结构

4. 适配跨环境导入需求

因为你需要把导出的JSON导回其他环境,需要额外重写资源类的before_save_instance方法,解析嵌套的关联数据:

class BookResource(resources.ModelResource):
    # ... 上面的字段声明和脱水方法保留不变

    def before_save_instance(self, instance, row, **kwargs):
        # 解析嵌套的作者数据,不存在则自动创建
        author_data = row.get("Author")
        if author_data:
            author, _ = Author.objects.get_or_create(name=author_data["name"])
            instance.author = author
        
        # 解析嵌套的分类数据,不存在则自动创建
        categories_data = row.get("categories", [])
        # 多对多字段要等实例保存后再赋值
        self._pending_categories = []
        for cat_data in categories_data:
            cat, _ = Category.objects.get_or_create(name=cat_data["name"])
            self._pending_categories.append(cat)

    def after_save_instance(self, instance, row, **kwargs):
        # 保存后给多对多字段赋值
        if hasattr(self, "_pending_categories"):
            instance.categories.set(self._pending_categories)
            del self._pending_categories

5. 导入调用示例

from import_export.results import RowResult

# 传入导出的JSON数据
resource = BookResource()
result = resource.import_data(dataset, dry_run=False)
# 可通过result.has_errors()检查是否导入出错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 22:15:03