Python 在kwargs.pop中获取KeyError,即使我通过了参数

Python 在kwargs.pop中获取KeyError,即使我通过了参数,python,keyerror,keyword-argument,Python,Keyerror,Keyword Argument,我有以下代码 # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models from .validators import audio_validator # Create your models here. from django.forms import forms from django.template.defaultfilters import files

我有以下代码

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

from .validators import audio_validator

# Create your models here.

from django.forms import forms
from django.template.defaultfilters import filesizeformat
from django.utils.translation import ugettext_lazy as _

MAX_FILE_SIZE=20971520

UPLOAD_TO = 'uploads'

class ContentTypeRestrictedFileField(models.FileField):

    def __init__(self, *args, **kwargs):
        self.content_types = kwargs.pop("content_types")
        self.max_upload_size = kwargs.pop("max_upload_size")

        super(ContentTypeRestrictedFileField, self).__init__(*args, **kwargs)

    def clean(self, *args, **kwargs):
        data = super(ContentTypeRestrictedFileField, self).clean(*args, **kwargs)

        file = data.file
        try:
            content_type = file.content_type
            if content_type in self.content_types:
                if file._size > self.max_upload_size:
                    raise forms.ValidationError(_('Please keep filesize under %s. Current filesize %s') % (filesizeformat(self.max_upload_size), filesizeformat(file._size)))
            else:
                raise forms.ValidationError(_('Filetype not supported.'))
        except AttributeError:
            pass

        return data

class AudioFile(models.Model):
    file_name = models.CharField(max_length=100)
    audio_file = ContentTypeRestrictedFileField(upload_to=UPLOAD_TO, validators=[audio_validator], content_types=['audio/aac', 'audio/mpeg', 'audio/ogg', 'audio/x-wav', 'audio/webm', 'audio/3gpp',], max_upload_size=MAX_FILE_SIZE)
    uploaded_at = models.DateTimeField(auto_now_add=True)
正如您所看到的,我正在以列表的形式传递
内容类型
,但它不起作用。 当我运行`./manage.py migrate时,我得到

raceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 184, in handle
    ProjectState.from_apps(apps),
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 230, in from_apps
    model_state = ModelState.from_model(model)
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 432, in from_model
    fields.append((name, field.clone()))
  File "/home/student/PycharmProjects/nightenv/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 469, in clone
    return self.__class__(*args, **kwargs)
  File "/home/student/PycharmProjects/tonightcore/nightcore/models.py", line 34, in __init__
    self.content_types = kwargs.pop("content_types")
KeyError: u'content_types'

在异常之前。

阅读文档了解
pop
的工作原理:

In [65]: dict.pop?
Docstring:
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised
Type:      method_descriptor

现在检查堆栈跟踪。看起来django试图以某种方式实例化对象,而不传入必需的关键字args。因此,最好只在
pop

中添加一个默认值,阅读文档了解
pop
的工作原理:

In [65]: dict.pop?
Docstring:
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised
Type:      method_descriptor

现在检查堆栈跟踪。看起来django试图以某种方式实例化对象,而不传入必需的关键字args。因此,最好只在
pop

中添加一个默认值,Django似乎实际上调用了
ContentTypeRestrictedFileField
,而没有我出于某种原因传递的
kwargs

如果我按照一些用户的建议打印(kwargs),我发现这些自定义参数不存在

也许Django会对所有模型文件都这样做

我在
kwargs.pop
中添加了一个默认参数,现在可以使用了。甚至文件验证也可以工作

我甚至通过删除Django的默认文件扩展名验证器进行了测试

def __init__(self, *args, **kwargs):
    print(kwargs)
    self.content_types = kwargs.pop("content_types", [])
    self.max_upload_size = kwargs.pop("max_upload_size", 5242880)

Django似乎实际上调用了
ContentTypeRestrictedFileField
,而没有使用我出于某种原因传递的
kwargs

如果我按照一些用户的建议打印(kwargs),我发现这些自定义参数不存在

也许Django会对所有模型文件都这样做

我在
kwargs.pop
中添加了一个默认参数,现在可以使用了。甚至文件验证也可以工作

我甚至通过删除Django的默认文件扩展名验证器进行了测试

def __init__(self, *args, **kwargs):
    print(kwargs)
    self.content_types = kwargs.pop("content_types", [])
    self.max_upload_size = kwargs.pop("max_upload_size", 5242880)

您可以轻松地将默认参数添加到两个self_变量(
self.content_类型
self.max_upload_大小
)中,如下所示

def __init__(self, *args, **kwargs):
    self.content_types = kwargs.pop("content_types", [])
    self.max_upload_size = kwargs.pop("max_upload_size", [])

您可以轻松地将默认参数添加到两个self_变量(
self.content_类型
self.max_upload_大小
)中,如下所示

def __init__(self, *args, **kwargs):
    self.content_types = kwargs.pop("content_types", [])
    self.max_upload_size = kwargs.pop("max_upload_size", [])

如果您在
\uuuu init\uuuuu
方法的第一行打印
kwargs
,您会看到什么?我认为
AudioFile
可能不会引发异常,“也许是django本身的初始化过程。”哈帕尔补充到answer@Yu-LinChen补充到回答中如果你在
\uuuu init\uuuuu
方法的第一行打印
kwargs
,你会看到什么?我想这个例外可能不是由
音频文件引起的,“也许是django本身的初始化过程。”哈帕尔补充到answer@Yu-林晨补充道:
是什么意思?我是confused@LonelyNeuron看起来是另一种选择answer@Lonely神经元做得很好。
是什么意思?我是confused@LonelyNeuron看起来是另一种选择answer@Lonely做得很好。