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

如何将字典列表中的数据保存到Django的Pokemon模型中

实现步骤

1. 模型修正(必做)

你当前定义的Pokemon模型中evolution字段为IntegerField类型,但原始数据中evolution存储的是进化后的宝可梦名称字符串,无法直接存入,有两种修正方案:

  • 方案1:直接存储进化后的宝可梦名称,修改字段为:
evolution = models.CharField(max_length=255, null=True, blank=True)
  • 方案2:存储进化后宝可梦的id(更符合数据库设计规范),修改为自关联外键:
evolution = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='pre_evolution')

修改完成后执行python manage.py makemigrations和python manage.py migrate更新数据库结构。

2. 数据处理与存储

方案A:直接用Django ORM批量写入(适合脚本/初始化场景)

代码示例,直接在Django shell或者自定义管理命令中运行:

# 你的原始数据
pokemon_data = [
    {'evolution': 'charizard',
    'height': 11,
    'id_pokemon': '5',
    'name': 'charmeleon',
    'stats': [[80, 'speed'],
            [65, 'special-defense'],
            [80, 'special-attack'],
            [58, 'defense'],
            [64, 'attack'],
            [58, 'hp']],
    'weight': 190},
    {'evolution': 'charmeleon',
    'height': 6,
    'id_pokemon': '4',
    'name': 'charmander',
    'stats': [[65, 'speed'],
            [50, 'special-defense'],
            [60, 'special-attack'],
            [43, 'defense'],
            [52, 'attack'],
            [39, 'hp']],
    'weight': 85},
    {'evolution': 'None',
    'height': 17,
    'id_pokemon': '6',
    'name': 'charizard',
    'stats': [[100, 'speed'],
            [85, 'special-defense'],
            [109, 'special-attack'],
            [78, 'defense'],
            [84, 'attack'],
            [78, 'hp']],
    'weight': 905}
]

# 预生成宝可梦名称到ID的映射(仅方案2需要)
name_to_id = {item['name']: int(item['id_pokemon']) for item in pokemon_data}

instance_list = []
for item in pokemon_data:
    # 转换stats为字段对应字典
    stats = {stat[1].replace('-', '_'): stat[0] for stat in item['stats']}
    # 处理evolution字段
    if item['evolution'] == 'None':
        evolution_val = None
    else:
        # 方案1:直接用原始值
        # evolution_val = item['evolution']
        # 方案2:转换为对应id
        evolution_val = name_to_id[item['evolution']]
    # 构造实例
    instance_list.append(Pokemon(
        id_pokemon = int(item['id_pokemon']),
        name = item['name'],
        weight = item['weight'],
        height = item['height'],
        special_defense = stats['special_defense'],
        special_attack = stats['special_attack'],
        defense = stats['defense'],
        attack = stats['attack'],
        hp = stats['hp'],
        speed = stats['speed'],
        evolution = evolution_val
    ))

# 批量写入数据库,ignore_conflicts=True避免主键重复报错
Pokemon.objects.bulk_create(instance_list, ignore_conflicts=True)

方案B:配合Django REST Framework序列化器写入(适合接口接收数据场景)

先定义序列化器:

from rest_framework import serializers
from .models import Pokemon

class PokemonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Pokemon
        fields = '__all__'

数据处理逻辑:

# 先按方案A的逻辑预处理数据,把stats展开、evolution、id_pokemon转成对应格式,得到processed_data列表
serializer = PokemonSerializer(data=processed_data, many=True)
if serializer.is_valid(raise_exception=True):
    serializer.save()

注意事项

  • 如果需要更新已存在的宝可梦数据,可将bulk_create替换为bulk_update,指定更新字段即可
  • 批量插入的执行效率远高于循环单条save,数据量较大时推荐使用
  • 序列化器会自动做字段类型校验,出现报错可通过serializer.errors定位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:36:02