如何使用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
相关产品推荐
相关产品推荐

