尝试将JSON导入Django数据库时出错 - TypeError:字符串索引必须是整数

时间:2013-08-25 16:48:32

标签: python database django json

我自己一直在自学编程不到一个月。我正在尝试构建一个Django站点来帮助这个过程。我花了最近3天的时间来寻找解决这个问题的方法无济于事。

我从Github上的某个人那里偷了这个代码,并且在调用专门编写它的JSON URL文件时它工作正常。但我一直在尝试修改它以使用另一个JSON URL文件,但它无法正常工作。它是一个命令文件,用于将数据导入数据库。所以这是我运行命令时会发生的事情:

PS C:\django-1.5.1\dota\mysite> python manage.py update_items
Fetching item list..
TypeError: string indices must be integers

如果下面的代码太多,我很抱歉,我真的不知道人们会隐含地知道什么样的事情。我正在尝试从此JSON文件中列出的每个游戏项导入字段。我只是从2个字段开始尝试使其正常工作。

您可以从以下网址查看JSON文件,但格式如下:

{
"itemdata": {
    "blink": {
        "id": 1,
        "img": "blink_lg.png",
        "dname": "Blink Dagger",
        "qual": "component",
        "cost": 2150,
        "desc": "Active: Blink - Teleport to a target point up to 1200 units away.  If damage is taken from an enemy hero, Blink Dagger cannot be used for 3 seconds.",
        "attrib": "",
        "mc": 75,
        "cd": 12,
        "lore": "The fabled dagger used by the fastest assassin ever to walk the lands.",
        "components": null,
        "created": false
    },
    "blades_of_attack": {
        "id": 2,

以下是与命令文件update_items.py相关的4个文件:

models.py - 此模型定义数据库字段

from django.db import models

class Item(models.Model):
    unique_id = models.IntegerField(unique=True)
    dname = models.CharField(max_length=255)

    def __unicode__(self):
        return self.dname

update_items.py - 这是将json数据导入数据库的命令文件

from django.core.management.base import BaseCommand, CommandError
from django.core.management.base import NoArgsCommand
from items.utils.api import SteamWrapper
from items.models import Item

class Command(NoArgsCommand):
help = 'Fetches and updates the items'

def update_item(self, item):
    try:
        db_item = Item.objects.get(unique_id=item['id'])
        print 'Updating %s..' % item['dname']
    except Item.DoesNotExist:
        print 'Creating %s..' % item['dname']
    db_item = Item()
    db_item.unique_id = item['id']
    db_item.dname = item['dname']
    db_item.save()
    print 'Done.'

def fetch_items(self, result):
        try:
            for item in result['itemdata']:
            self.update_item(item)
        except KeyError:
            print "Error while contacting steam API. Please retry."

def handle(self, *args, **options):
      self.stdout.write('Fetching item list..')
      result = SteamWrapper.get_item_list()
      self.fetch_items(result)
      self.stdout.write('Finished.')

api.py - 这是web api调用函数的事情

import requests
from mysite import settings_local

class   SteamWrapper():
    ''' Steam API wrapper '''

API_KEY = settings_local.STEAM_API_KEY

@classmethod
def _item_send_request(cls, endpoint, *args, **kwargs):
    params = {'key': cls.API_KEY}
    params.update(kwargs)
    request = requests.get(endpoint, params=params)
    return request.json()

@classmethod
def get_item_list(cls):
    return cls._item_send_request(settings_local.DOTA2_ITEM_LIST_ENDPOINT)

local-settings.py

DOTA2_ITEM_LIST_ENDPOINT = 'http://www.dota2.com/jsfeed/itemdata'

那么任何想法?非常感谢...

2 个答案:

答案 0 :(得分:1)

问题在于:

for item in result['itemdata']

itemdata是一个 dict (dicts)。在Python中,迭代dict会产生:所以item有“blink”,“blades_of_attack”等等,因此出错。

您似乎根本不想要密钥,因此您应该遍历result['itemdata'].values()

(请注意update_item中存在缩进错误:行db_item = Item()应缩进except,否则将始终创建新项目。)

答案 1 :(得分:0)

def handle(self, *args, **options):
      self.stdout.write('Fetching item list..')
      result = SteamWrapper.get_item_list
      self.fetch_items(result)
      self.stdout.write('Finished.')

result = SteamWrapper.get_item_list行使result指向名为SteamWrapper的{​​{1}}方法。也许你打算通过输入get_item_list

来打电话