【问题标题】:create() takes 1 positional argument but 2 were given? Djangocreate() 接受 1 个位置参数但给出了 2 个?姜戈
【发布时间】:2020-01-11 20:34:58
【问题描述】:

我很困惑为什么当我运行这段代码时它会返回一个错误

create() 接受 1 个位置参数,但给出了 2 个

if request.method == "POST":
my_form = RawProductCreateForm(request.POST)
if my_form.is_valid():
    Product.objects.create(my_form.cleaned_data)

但是当我修改 create 方法并在传递清理后的数据之前添加 ** 时,它可以工作!

Product.objects.create(**my_form.cleaned_data)

【问题讨论】:

标签: python django cleaned-data


【解决方案1】:

当您尝试在没有指向模型中定义的字段的情况下插入数据时会发生这种情况。 要解决此问题,您必须在 create() 中使用赋值运算符传递字段名称。

Product.objects.create(field1="<field 1 data>", field2=<field2 data>)

【讨论】:

    【解决方案2】:

    底层的 create 函数看起来不像这样:

    def create(self, **data):
       pass
    

    如您所见,您有一个位置参数self,另一个只是关键字字典。当你像这样调用这个函数时:

    Product.objects.create(my_form.cleaned_data)
    

    您传递了两个位置参数,一个是objects,这是python处理类和方法的方式,另一个是my_form.cleaned_data,但该函数只使用一个位置参数和任意数量的命名参数。 在第二次通话中:

    Product.objects.create(**my_form.cleaned_data)
    

    假设my_form.cleaned_data 看起来像这样:

    { 
      'age': 1,
      'name': 'good product'
    }
    

    所以第二次调用的等价物是

    Product.objects.create(name='good product', age=1)
    

    如您所见,您只有一个位置参数objects 和2 个命名参数。 在创建函数中,您可以参考如下数据:

    def create(self, **data):
       name = data['name']
       age = data['age']
    

    【讨论】:

    • 所以用 ** 传递cleaned_data 告诉函数将cleaned_data 视为kwarg 对吗?
    • 正确。简而言之,它将字典转换为命名参数
    【解决方案3】:

    这是因为create 接受关键字参数,例如

        Product.objects.create(product_name="Dish Soap", product_price=73)
    

    在告诉模型将my_form.cleaned_data 视为关键字参数字典之前放置**

    【讨论】:

      猜你喜欢
      • 2018-11-15
      • 2019-03-12
      • 2016-10-13
      • 2019-04-20
      • 2014-07-19
      • 2016-08-09
      • 2020-01-30
      • 2019-08-02
      • 1970-01-01
      相关资源
      最近更新 更多