【问题标题】:Django TypeError when creating objects in a model using dictionary使用字典在模型中创建对象时出现 Django TypeError
【发布时间】:2017-05-16 07:56:05
【问题描述】:

我正在尝试将字典中的项目传递给模型,每个键、值对都成为一个对象。

d1 = {'Alex': 3.0, 'Chriss': 7.42, 'Robert': 9.13}

这是模型:

class Team_one(models.Model):
    name = models.CharField(max_length=100)
    score = models.FloatField(default=0.0)

当我试图在 shell 中做一个例子时,我得到一个类型错误

这是一个例子:

x = {'Alex': 3.0}
Team_one.objects.create(**x)

m = Team_one(**x)
m.save()

这是错误:

`TypeError: 'Alex' is an invalid keyword argument for this function`

【问题讨论】:

  • 我认为这个问题很简单。你应该试着理解解包字典的含义。

标签: python django dictionary django-models


【解决方案1】:

您的模型类 Team_one 没有属性 Alex

在您的字典中,您需要具有 Alex3.0 值的键 namescore

最终您可以将检索到的字典转换为字典列表:

team_one = [{'name': name, 'score': score} for name, score in d1.items()]

这是您将获得的输出:

[
    {'score': 7.42, 'name': 'Chriss'},
    {'score': 3.0, 'name': 'Alex'},
    {'score': 9.13, 'name': 'Robert'}
]

现在您可以遍历列表并创建对象。

【讨论】:

    【解决方案2】:

    是的,你肯定会得到一个 TypeError,因为你使用字典只是为了你的值。字典表示键值存储,因此在您的情况下,您必须为它们指定键和值:

    {
        'name': 'Alex',
        'score': 3.0,
    }
    

    如果你想创建多个对象,你可以只使用一个 for 循环:

    team_ones = [{'name': 'Alex', 'score': 3.0}, {'name': 'Chriss', 'score': 7.42}, {'name': 'Robert', 'score': 9.13}]
    
    for team_one in team_ones:
        Team_one.objects.create(**team_one)
    

    【讨论】:

    • 好的,但是当字典从其他函数返回时,我怎样才能以这种方式制作字典:{'Alex': 3.0, 'Chriss': 7.42, 'Robert': 9.13}?跨度>
    • 这很简单,短期内你可以使用:return_value = {'Alex': 3.0, 'Chriss': 7.42, 'Robert': 9.13} your_preferred_value = {name: key, score: value对于键,值在 return_value.items()}
    【解决方案3】:

    这应该可行:

    for key, value in d1.items():
        Time_team.objects.create(name=key, score=value)
    

    它使用您最初的 d1 字典。

    【讨论】:

    • 现在可以正常工作了。这也是一个非常简单的解决方案。
    【解决方案4】:

    TL:DR;

    您应该更改您的字典以匹配您的模型:

    x = {
       'name': 'Alex',
       'score': 3.0
    }
    Team_one.objects.create(**x)
    


    说明

    当你创建一个 django 对象时,create 函数需要 **kwargs 来匹配模型。在您的情况下,对 create() 的正确调用是:

    Team_one.objects.create(name='Alex', score=3.0)
    

    当您“解包” 字典 (**x) 时,会发生键作为参数名称传递而值作为参数值传递的情况。您最初的操作导致了对create()错误调用:

    Team_one.objects.create(Alex=3.0)
    

    因此,通过将字典更改为以下形式,您可以在create() 函数中正确“解包”它:

    arguments = {
        'name': 'a_name',
        'score': 2.0
    }
    

    因评论而编辑:

    你应该做的是:

    1. 更改函数返回字典的方式
    2. 或修改您收到的字典以匹配上述内容
    3. 或者调用create()而不“解包”任何东西:

      for item in d1.keys():
          Team_one.objects.create(name=item, score=d1[item])
      

    【讨论】:

    • 好的,它可以工作,但是当我的字典在另一个函数中返回时,我该怎么办 d1 = {'Alex': 3.0, 'Chriss': 7.42, 'Robert': 9.13} ?
    • 我添加了一个编辑来让你开始@NitaAlexandru。
    • 很详尽的回答,尤其是编辑后的总结。不幸的是,我只能投票一次。
    • @cezar 谢谢 :) 你的文章很短而且很重要,这也很棒!
    猜你喜欢
    • 2017-01-05
    • 2021-02-02
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多