如何抑制 Django 中的弃用警告?
How to suppress the deprecation warnings in Django?
每次我使用 django-admin
命令时——即使是在 TAB 完成时——它都会抛出一个 RemovedInDjango19Warning
(如果我使用 test 命令)。我怎样才能抑制这些警告?
我正在使用 Django 1.8 和 Python 3.4(在虚拟环境中)。据我所知,所有这些警告都来自库而不是我的代码。
例子
这里有一些例子:
…/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
return f(*args, **kwds)
…/lib/python3.4/site-packages/django/contrib/admin/util.py:7: RemovedInDjango19Warning: The django.contrib.admin.util module has been renamed. Use django.contrib.admin.utils instead.
"Use django.contrib.admin.utils instead.", RemovedInDjango19Warning)
…/lib/python3.4/site-packages/django/templatetags/future.py:25: RemovedInDjango19Warning: Loading the ``url`` tag from the ``future`` library is deprecated and will be removed in Django 1.9. Use the default ``url`` tag instead.
RemovedInDjango19Warning)
更新
从 Django 1.11 版 (release notes) 开始,弃用警告不再默认响亮。所以我想这不再是问题,因为 1.11 是最后一个支持 Python 2 的版本,并且还提供长期支持。
在manage.py中,将此添加到顶行--
#!/usr/bin/env PYTHONWARNINGS=ignore python
这将抑制所有警告,我同意如果您使用大量第三方库,在某些情况下这可能是不受欢迎的。
免责声明:仅在您已经看到警告至少 1,000 次之后才推荐,并且应该在升级 Django 时删除。
注意:这可能会在某些平台上产生一些不良影响,例如吞噬比警告更多的输出。
这个标准的 django 脚本为您添加 TAB 补全 bash - https://github.com/django/django/blob/master/extras/django_bash_completion
未定义 PYTHONWARNINGS - 控制台出错。添加 export PYTHONWARNINGS="ignore" 并在 _django_completion()
中取消设置 PYTHONWARNINGS
原函数:
_django_completion()
{
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
DJANGO_AUTO_COMPLETE=1 ) )
}
我的版本。在其他情况下不要破坏基本行为。
_django_completion()
{
export PYTHONWARNINGS="ignore"
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
DJANGO_AUTO_COMPLETE=1 ) )
unset PYTHONWARNINGS
}
向 settings.py 添加日志过滤器可以抑制这些控制台警告(至少对于 Django 1.7、Python 3.4 中的 manage.py 命令)。
过滤器可以有选择地抑制警告。以下代码为控制台创建一个新的 "suppress_deprecated" 过滤器并将其附加到默认日志记录过滤器。将此块添加到 settings.py 以配置 LOGGING 变量:
import logging, copy
from django.utils.log import DEFAULT_LOGGING
LOGGING = copy.deepcopy(DEFAULT_LOGGING)
LOGGING['filters']['suppress_deprecated'] = {
'()': 'mysite.settings.SuppressDeprecated'
}
LOGGING['handlers']['console']['filters'].append('suppress_deprecated')
class SuppressDeprecated(logging.Filter):
def filter(self, record):
WARNINGS_TO_SUPPRESS = [
'RemovedInDjango18Warning',
'RemovedInDjango19Warning'
]
# Return false to suppress message.
return not any([warn in record.getMessage() for warn in WARNINGS_TO_SUPPRESS])
如果根网站模块(或过滤器位置 and/or 名称)不同,'mysite.settings.SuppressDeprecated' 字符串需要更改。
出于某种原因,Fred Schleifer 提供的解决方案在 Django 1.9 中对我不起作用,所以我不得不寻找不同的解决方案。
在 settings.py
中,我设置了一个自定义 LOGGING_CONFIG
函数:
LOGGING_CONFIG = 'my_project.logging_utils.configure'
然后我定义了自定义 my_project.logging_utils
模块,如下所示:
from logging.config import dictConfig
import warnings
from django.utils.deprecation import RemovedInDjango110Warning
IGNORE_DJANGO_110_WARNINGS = {
# This is a specific warning raised by a third-party library.
r'rest_framework_swagger\.urls': r'django\.conf\.urls\.patterns\(\) is deprecated.*'
}
def configure(settings):
dictConfig(settings)
for module, message in IGNORE_DJANGO_110_WARNINGS.items():
warnings.filterwarnings(
action='ignore',
category=RemovedInDjango110Warning,
module=module,
message=message
)
IGNORE_DJANGO_110_WARNINGS
字典包含从模块名称到它们引发的警告的正则表达式的映射。我选择在我抑制的警告类型中非常具体,因为我仍然想看到那些我没想到的警告。随着个别 third-party 个库的更新,我将从字典中删除它们的关联条目。
在 django 1.7 中,引入了一个新设置SILENCED_SYSTEM_CHECKS
来抑制警告
A list of identifiers of messages generated by the system check
framework (i.e. ["models.W001"]) that you wish to permanently
acknowledge and ignore. Silenced warnings will no longer be output to
the console; silenced errors will still be printed, but will not
prevent management commands from running.
Documentation could be found here
这是一个list of all the checks to suppress
示例:
如果您希望抑制 TEMPLATES_
警告,
The standalone TEMPLATE_* settings were deprecated in Django 1.8
您的设置将是:
SILENCED_SYSTEM_CHECKS = ["1_8.W001"]
以上都不适用于我,django 1.9。我通过将以下行添加到 settings.py:
来修复此问题
import logging
def filter_deprecation_warnings(record):
warnings_to_suppress = [
'RemovedInDjango110Warning'
]
# Return false to suppress message.
return not any([warn in record.getMessage()
for warn in warnings_to_suppress])
warn_logger = logging.getLogger('py.warnings')
warn_logger.addFilter(filter_deprecation_warnings)
Django 通过标准 python 警告模块发出警告。如果您的 python 项目抛出警告并且它们目前是 "acceptable",只需使用 warnings.filterwarnings()
或 warnings.simplefilter()
。我不确定这些 "best" 的位置在哪里,但我已将它们放入我的 common_settings.py 文件中(对我来说,这是一个不变的签入文件,由 local_settings.py).
例如:
warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning, module='django.template.utils', lineno=37)
唉,关于使系统检查静音的评论在这里不起作用,因为您的示例没有抛出系统检查错误。
在我的 Django 1.8 项目的其他依赖项中查看弃用警告时,使用
python -Wd manage.py runserver
,我能够通过临时添加
过滤掉 Django 弃用警告
import warnings
from django.utils.deprecation import RemovedInDjango110Warning
warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning)
到我的 settings.py
(大概可以在启动时加载的任何模块中)。我不知道如何将过滤器作为额外的 -W
选项包含在内,即
python -Wd -Wi::RemovedInDjango110Warning manage.py runserver
导致 Invalid -W option ignored: unknown warning category: 'RemovedInDjango110Warning'
。
# in settings.py
import warnings
from django.utils.deprecation import RemovedInDjango20Warning
DEBUG = True
if DEBUG:
warnings.simplefilter('default')
warnings.filterwarnings('ignore', category=RemovedInDjango20Warning)
# use it if you annoyed by DeprecationWarning
warnings.filterwarnings('ignore', category=DeprecationWarning)
对于仅命令行界面的快速解决方案,执行时在 manage.py 前加上 python -W ignore
,如:
python -W ignore manage.py runserver
-或-
python -W ignore manage.py shell_plus
-或-
python -W ignore manage.py makemigrations
这对我有用,在 运行 Django 1.9 时抑制所有 Django 1.10 弃用警告。
我会把这个留给新人:
至于 django 1.11
默认情况下弃用警告不再响亮。例如要激活它们 运行 python -Wd manage.py runserver
。
我目前在使用 Django 1.8 时遇到同样的问题。我们决定只在 DEBUG 模式下显示它们,而不是完全抑制这些警告。
我们可以在日志设置中添加控制台处理程序,并使用此处理程序来捕获 py.warnings。这是代码片段,
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue'
},
...
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'standard',
},
...
},
'loggers': {
'py.warnings': {
'handlers': ['console', ],
'level': 'INFO',
'propagate': False
},
...
}
完整的 Django 设置文件:https://github.com/haiwen/seahub/blob/21c827c68047e13700fe102d22a3f5515b22af89/seahub/settings.py#L484
每次我使用 django-admin
命令时——即使是在 TAB 完成时——它都会抛出一个 RemovedInDjango19Warning
(如果我使用 test 命令)。我怎样才能抑制这些警告?
我正在使用 Django 1.8 和 Python 3.4(在虚拟环境中)。据我所知,所有这些警告都来自库而不是我的代码。
例子
这里有一些例子:
…/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes. return f(*args, **kwds)
…/lib/python3.4/site-packages/django/contrib/admin/util.py:7: RemovedInDjango19Warning: The django.contrib.admin.util module has been renamed. Use django.contrib.admin.utils instead. "Use django.contrib.admin.utils instead.", RemovedInDjango19Warning)
…/lib/python3.4/site-packages/django/templatetags/future.py:25: RemovedInDjango19Warning: Loading the ``url`` tag from the ``future`` library is deprecated and will be removed in Django 1.9. Use the default ``url`` tag instead. RemovedInDjango19Warning)
更新
从 Django 1.11 版 (release notes) 开始,弃用警告不再默认响亮。所以我想这不再是问题,因为 1.11 是最后一个支持 Python 2 的版本,并且还提供长期支持。
在manage.py中,将此添加到顶行--
#!/usr/bin/env PYTHONWARNINGS=ignore python
这将抑制所有警告,我同意如果您使用大量第三方库,在某些情况下这可能是不受欢迎的。
免责声明:仅在您已经看到警告至少 1,000 次之后才推荐,并且应该在升级 Django 时删除。
注意:这可能会在某些平台上产生一些不良影响,例如吞噬比警告更多的输出。
这个标准的 django 脚本为您添加 TAB 补全 bash - https://github.com/django/django/blob/master/extras/django_bash_completion
未定义 PYTHONWARNINGS - 控制台出错。添加 export PYTHONWARNINGS="ignore" 并在 _django_completion()
中取消设置 PYTHONWARNINGS原函数:
_django_completion()
{
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
DJANGO_AUTO_COMPLETE=1 ) )
}
我的版本。在其他情况下不要破坏基本行为。
_django_completion()
{
export PYTHONWARNINGS="ignore"
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
DJANGO_AUTO_COMPLETE=1 ) )
unset PYTHONWARNINGS
}
向 settings.py 添加日志过滤器可以抑制这些控制台警告(至少对于 Django 1.7、Python 3.4 中的 manage.py 命令)。
过滤器可以有选择地抑制警告。以下代码为控制台创建一个新的 "suppress_deprecated" 过滤器并将其附加到默认日志记录过滤器。将此块添加到 settings.py 以配置 LOGGING 变量:
import logging, copy
from django.utils.log import DEFAULT_LOGGING
LOGGING = copy.deepcopy(DEFAULT_LOGGING)
LOGGING['filters']['suppress_deprecated'] = {
'()': 'mysite.settings.SuppressDeprecated'
}
LOGGING['handlers']['console']['filters'].append('suppress_deprecated')
class SuppressDeprecated(logging.Filter):
def filter(self, record):
WARNINGS_TO_SUPPRESS = [
'RemovedInDjango18Warning',
'RemovedInDjango19Warning'
]
# Return false to suppress message.
return not any([warn in record.getMessage() for warn in WARNINGS_TO_SUPPRESS])
如果根网站模块(或过滤器位置 and/or 名称)不同,'mysite.settings.SuppressDeprecated' 字符串需要更改。
出于某种原因,Fred Schleifer 提供的解决方案在 Django 1.9 中对我不起作用,所以我不得不寻找不同的解决方案。
在 settings.py
中,我设置了一个自定义 LOGGING_CONFIG
函数:
LOGGING_CONFIG = 'my_project.logging_utils.configure'
然后我定义了自定义 my_project.logging_utils
模块,如下所示:
from logging.config import dictConfig
import warnings
from django.utils.deprecation import RemovedInDjango110Warning
IGNORE_DJANGO_110_WARNINGS = {
# This is a specific warning raised by a third-party library.
r'rest_framework_swagger\.urls': r'django\.conf\.urls\.patterns\(\) is deprecated.*'
}
def configure(settings):
dictConfig(settings)
for module, message in IGNORE_DJANGO_110_WARNINGS.items():
warnings.filterwarnings(
action='ignore',
category=RemovedInDjango110Warning,
module=module,
message=message
)
IGNORE_DJANGO_110_WARNINGS
字典包含从模块名称到它们引发的警告的正则表达式的映射。我选择在我抑制的警告类型中非常具体,因为我仍然想看到那些我没想到的警告。随着个别 third-party 个库的更新,我将从字典中删除它们的关联条目。
在 django 1.7 中,引入了一个新设置SILENCED_SYSTEM_CHECKS
来抑制警告
A list of identifiers of messages generated by the system check framework (i.e. ["models.W001"]) that you wish to permanently acknowledge and ignore. Silenced warnings will no longer be output to the console; silenced errors will still be printed, but will not prevent management commands from running.
Documentation could be found here
这是一个list of all the checks to suppress 示例:
如果您希望抑制 TEMPLATES_
警告,
The standalone TEMPLATE_* settings were deprecated in Django 1.8
您的设置将是:
SILENCED_SYSTEM_CHECKS = ["1_8.W001"]
以上都不适用于我,django 1.9。我通过将以下行添加到 settings.py:
来修复此问题import logging
def filter_deprecation_warnings(record):
warnings_to_suppress = [
'RemovedInDjango110Warning'
]
# Return false to suppress message.
return not any([warn in record.getMessage()
for warn in warnings_to_suppress])
warn_logger = logging.getLogger('py.warnings')
warn_logger.addFilter(filter_deprecation_warnings)
Django 通过标准 python 警告模块发出警告。如果您的 python 项目抛出警告并且它们目前是 "acceptable",只需使用 warnings.filterwarnings()
或 warnings.simplefilter()
。我不确定这些 "best" 的位置在哪里,但我已将它们放入我的 common_settings.py 文件中(对我来说,这是一个不变的签入文件,由 local_settings.py).
例如:
warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning, module='django.template.utils', lineno=37)
唉,关于使系统检查静音的评论在这里不起作用,因为您的示例没有抛出系统检查错误。
在我的 Django 1.8 项目的其他依赖项中查看弃用警告时,使用
python -Wd manage.py runserver
,我能够通过临时添加
过滤掉 Django 弃用警告import warnings
from django.utils.deprecation import RemovedInDjango110Warning
warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning)
到我的 settings.py
(大概可以在启动时加载的任何模块中)。我不知道如何将过滤器作为额外的 -W
选项包含在内,即
python -Wd -Wi::RemovedInDjango110Warning manage.py runserver
导致 Invalid -W option ignored: unknown warning category: 'RemovedInDjango110Warning'
。
# in settings.py
import warnings
from django.utils.deprecation import RemovedInDjango20Warning
DEBUG = True
if DEBUG:
warnings.simplefilter('default')
warnings.filterwarnings('ignore', category=RemovedInDjango20Warning)
# use it if you annoyed by DeprecationWarning
warnings.filterwarnings('ignore', category=DeprecationWarning)
对于仅命令行界面的快速解决方案,执行时在 manage.py 前加上 python -W ignore
,如:
python -W ignore manage.py runserver
-或-
python -W ignore manage.py shell_plus
-或-
python -W ignore manage.py makemigrations
这对我有用,在 运行 Django 1.9 时抑制所有 Django 1.10 弃用警告。
我会把这个留给新人:
至于 django 1.11
默认情况下弃用警告不再响亮。例如要激活它们 运行 python -Wd manage.py runserver
。
我目前在使用 Django 1.8 时遇到同样的问题。我们决定只在 DEBUG 模式下显示它们,而不是完全抑制这些警告。
我们可以在日志设置中添加控制台处理程序,并使用此处理程序来捕获 py.warnings。这是代码片段,
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue'
},
...
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'standard',
},
...
},
'loggers': {
'py.warnings': {
'handlers': ['console', ],
'level': 'INFO',
'propagate': False
},
...
}
完整的 Django 设置文件:https://github.com/haiwen/seahub/blob/21c827c68047e13700fe102d22a3f5515b22af89/seahub/settings.py#L484