尽管我传递了参数,但在 kwargs.pop 中出现 KeyError
Getting KeyError in kwargs.pop even though I pass the 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 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)
如您所见,我将 content_types
作为列表传递,但它不起作用。
当我 运行 `./manage.py 迁移时,我得到
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'
如果我 print(kwargs)
我明白了:
{'content_types': [u'audio/aac', u'audio/mpeg', u'audio/ogg', u'audio/x-wav', u'audio/webm', u'audio/3gpp'], 'max_upload_size': 20971520, 'upload_to': u'uploads', 'validators': [<django.core.validators.FileExtensionValidator object at 0x7fb90952a9d0>]}
{'upload_to': u'uploads', 'validators': [<django.core.validators.FileExtensionValidator object at 0x7fb909441090>]}
异常前
阅读有关 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 试图以某种方式实例化对象而不传递必需的关键字参数。所以最好只为 pop
添加一个默认值
似乎 Django 实际上是在调用 ContentTypeRestrictedFileField
而没有 kwargs
我出于某种原因通过了。
如果我按照某些用户的建议print(kwargs)
,我发现这些自定义参数不存在。
也许 Django 对所有 ModelFiled 都这样做。
我向 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_variables(self.content_types
和 self.max_upload_size
)...
def __init__(self, *args, **kwargs):
self.content_types = kwargs.pop("content_types", [])
self.max_upload_size = kwargs.pop("max_upload_size", [])
我有以下代码
# -*- 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)
如您所见,我将 content_types
作为列表传递,但它不起作用。
当我 运行 `./manage.py 迁移时,我得到
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'
如果我 print(kwargs)
我明白了:
{'content_types': [u'audio/aac', u'audio/mpeg', u'audio/ogg', u'audio/x-wav', u'audio/webm', u'audio/3gpp'], 'max_upload_size': 20971520, 'upload_to': u'uploads', 'validators': [<django.core.validators.FileExtensionValidator object at 0x7fb90952a9d0>]}
{'upload_to': u'uploads', 'validators': [<django.core.validators.FileExtensionValidator object at 0x7fb909441090>]}
异常前
阅读有关 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 试图以某种方式实例化对象而不传递必需的关键字参数。所以最好只为 pop
似乎 Django 实际上是在调用 ContentTypeRestrictedFileField
而没有 kwargs
我出于某种原因通过了。
如果我按照某些用户的建议print(kwargs)
,我发现这些自定义参数不存在。
也许 Django 对所有 ModelFiled 都这样做。
我向 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_variables(self.content_types
和 self.max_upload_size
)...
def __init__(self, *args, **kwargs):
self.content_types = kwargs.pop("content_types", [])
self.max_upload_size = kwargs.pop("max_upload_size", [])