44

Every time I'm using the django-admin command — even on TAB–completion — it throws a RemovedInDjango19Warning (and a lot more if I use the test command). How can I suppress those warnings?

I'm using Django 1.8 with Python 3.4 (in a virtual environment). As far as I can tell, all those warnings come from libraries not from my code.

Examples

Here are some examples:

  • …/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)

Update

Since Django version 1.11 (release notes) deprecating warnings are no longer loud by default. So I guess this won't be an issue anymore, since 1.11 is the last version to support Python 2 and also features long-term support.

Brutus
  • 7,139
  • 7
  • 36
  • 41
  • 8
    Django itself won't call any deprecated functions. All those warnings come from code in *your project* which calls that deprecated Django functionality. Although potentially they are being triggered by third-party libraries. – Daniel Roseman Apr 10 '15 at 14:48
  • 3
    I am having he same issue, I get around 12 deprecation warnings that come from 3rd party libraries and is very annoying since they trigger even for the autocomplete functionality. – Hassek Apr 14 '15 at 12:49

13 Answers13

30

Adding a logging filter to settings.py can suppress these console warnings (at least for manage.py commands in Django 1.7, Python 3.4).

A filter can selectively suppress warnings. The following code creates a new "suppress_deprecated" filter for the console and appends it to the default logging filters. Add this block to settings.py to configure the LOGGING variable:

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])

The 'mysite.settings.SuppressDeprecated' string needs to change if the root website module (or filter location and/or name) is different.

Fred Schleifer
  • 506
  • 1
  • 7
  • 7
  • 1
    While I like using `PYTHONWARNINGS` on a virtual environment basis (simple, fast and it's easy to switch between, local, staging, production…), this seems cleaner because only the *depreciation warnings* are filtered. Using multiple setting files would allow handling this differently on staging or production settings too. Not quiet sure why the `deepcopy` and what `'()': 'mysite.settings.SuppressDeprecated'` is for? Could this be archied with the logging API too (registering the filter and setting it for the console handler)? – Brutus Jul 02 '15 at 13:25
  • 2
    This approach is necessary if you have logging configured because the warnings module always logs to the py.warnings handler even when message would otherwise be filtered with e.g. `warnings.simplefilter('ignore', DeprecationWarning)` – Chris Adams Jul 02 '15 at 20:09
  • 3
    @Brutus: The motivation for the `deepcopy` is to respect `DEFAULT_LOGGING` as a global constant, just in case another module expects `DEFAULT_LOGGING` to be in its original state. The `'()'` dictionary key specifies a user-defined factory (for the filter), and this nested dictionary may also include instantiation parameters for the factory. The _User-defined objects_ section of the Python 3 docs for the logging.config module (logging in Python 2) provides more detail about the `'()'` key. The `DEFAULT_LOGGING` definition in django/utils/log.py helps illustrate how everything fits together. – Fred Schleifer Jul 05 '15 at 17:06
25

In django 1.7, a new setting was introduced SILENCED_SYSTEM_CHECKS to suppress warnings

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

Here is a list of all the checks to suppress Example:

If you wish to suppress the TEMPLATES_ warning,

The standalone TEMPLATE_* settings were deprecated in Django 1.8

your settings would be:

SILENCED_SYSTEM_CHECKS = ["1_8.W001"]
karthikr
  • 97,368
  • 26
  • 197
  • 188
  • 4
    Alas, these are actually separate to the Django deprecation warnings (handled by Python's "warnings.py" module). – Chris Lamb Mar 23 '16 at 08:51
  • `DEBUG=False` disable deprecation warnings, along with `SILENCED_SYSTEM_CHECKS` should do the job on production environments. On testing environments I don't see the issue. – Oberix Apr 12 '16 at 15:27
22

I'll leave this for newcomers:

As for django 1.11 deprecating warnings are no longer loud by default. To activate them run python -Wd manage.py runserver for example.

source

Willemoes
  • 5,752
  • 3
  • 30
  • 27
11

In manage.py, add this to the top line --

#!/usr/bin/env PYTHONWARNINGS=ignore python

This will suppress all warnings, which I agree can in some situations be undesirable if you're using a lot of third party libraries.

Disclaimer: Recommended only after you've already seen the warnings at least 1,000 too many times already, and should be removed when you upgrade Django.

Note: this may have some undesirable effects on some platforms, eg swallowing more output than just warnings.

s29
  • 2,027
  • 25
  • 20
  • Good workaround! I let some more time pass before accepting your answer though, because I generally use `django-admin` directly — as [recommended in the docs for working with multiple settings files](https://docs.djangoproject.com/en/1.8/ref/django-admin/) — and would prefer a solution, that disables the warnings for that, like setting the `-W ignore` flag globally or something along those lines. – Brutus May 01 '15 at 11:47
  • 4
    Also you can add it that to your `~/.profile` or `~/.bashrc` as a system variable. Something like: `export PYTHONWARNINGS=ignone` – slackmart May 14 '15 at 18:04
  • 2
    @sgmart: Nice, I didn't know of `PYTHONWARNINGS`. It's probably safer to set it in a virtualenv postactivate file or similar then in the bash settings. Getting warnings is all right, it's just that they mess with djangos autocomplete… – Brutus May 18 '15 at 09:19
  • I agree with you @Brutus. – slackmart May 20 '15 at 02:04
  • FWIW, re. your disclaimer, you don't have to take a big decision to hardcode in `manage.py`, you can just set an environment variable on process invocation. `PYTHONWARNINGS=ignore python manage.py ...` when you type it in the terminal or write it in a bash script. – JL Peyret Oct 08 '22 at 19:09
11

Nothing of the above have worked for me, django 1.9. I fixed this by adding the following lines to 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)
Ivan Vigasin
  • 111
  • 1
  • 3
  • I like this solution because it doesn't require changing the logging configuration outside of a single logger. I also needed to call `logging.captureWarnings(True)`. The filter function in this solution did not work, so I used `SuppressDeprecated` from https://stackoverflow.com/a/31103483/10840 – millerdev Aug 09 '17 at 15:42
9

While reviewing deprecation warnings in other dependencies of my Django 1.8 project, using

python -Wd manage.py runserver

, I was able to filter out Django deprecation warnings by temporarily adding

import warnings
from django.utils.deprecation import RemovedInDjango110Warning
warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning)

to my settings.py (can presumably be in any module that's loaded at startup). I couldn't figure out how to include the filter as an extra -W option, i.e.

python -Wd -Wi::RemovedInDjango110Warning manage.py runserver

resulted in Invalid -W option ignored: unknown warning category: 'RemovedInDjango110Warning'.

Donny Winston
  • 2,324
  • 1
  • 15
  • 13
5

For a quick command-line interface only solution, preface manage.py with python -W ignore when executing, as in:

python -W ignore manage.py runserver

-or-

python -W ignore manage.py shell_plus

-or-

python -W ignore manage.py makemigrations

This is working for me now, to suppress all of the Django 1.10 deprecation warnings while running Django 1.9.

Mark Chackerian
  • 21,866
  • 6
  • 108
  • 99
3

For some reason the solution provided by Fred Schleifer didn't work for me in Django 1.9, so I had to find a different solution.

In settings.py, I set up a custom LOGGING_CONFIG function:

LOGGING_CONFIG = 'my_project.logging_utils.configure'

Then I defined my custom my_project.logging_utils module like so:

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
        )

The IGNORE_DJANGO_110_WARNINGS dict contains a mapping from module names to regular expressions of warnings raised by them. I chose to be very specific in the kinds of warnings I suppressed, as I still wanted to see ones that I didn't expect. As individual third-party libraries are updated, I'll remove their associated entries from the dict.

Atul Varma
  • 303
  • 3
  • 7
3
# 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)
madjardi
  • 5,649
  • 2
  • 37
  • 37
2

This standart django script add TAB–completion for you bash - https://github.com/django/django/blob/master/extras/django_bash_completion

PYTHONWARNINGS is not defined - error in console. Add export PYTHONWARNINGS="ignore" and unset PYTHONWARNINGS in _django_completion()

Original function:

_django_completion()
{
    COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
                   COMP_CWORD=$COMP_CWORD \
                   DJANGO_AUTO_COMPLETE=1 $1 ) )
}

My version. Do not break the basic behavior in other cases.

_django_completion()
{
    export PYTHONWARNINGS="ignore"
    COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
                   COMP_CWORD=$COMP_CWORD \
                   DJANGO_AUTO_COMPLETE=1 $1 ) )
    unset PYTHONWARNINGS
}
Forester
  • 21
  • 2
  • 2
    Could you please elaborate more your answer adding a little more description about the solution you provide? – abarisone Jun 19 '15 at 07:07
2

Django puts warnings through the standard python warnings module. If your python project throws warnings and they're "acceptable" for the moment, just use warnings.filterwarnings() or warnings.simplefilter(). I'm not sure where the "best" place for these are, but I've dropped them into my common_settings.py file (For me, this is a unchanging, checked-in file, that is imported by local_settings.py).

Eg:

warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning, module='django.template.utils', lineno=37)

Alas the comment about silencing the system checks won't work, here, since your example isn't throwing a system-check error.

Chris Cogdon
  • 7,481
  • 5
  • 38
  • 30
1

I currently encounter this same issue when using Django 1.8. Instead of completely suppress those warnings, we decide to show them only in DEBUG mode.

We can add console handler in logging settings and use this handler to catch py.warnings. Here is the code snippet,

'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
    },
    ...
}

The complete Django settings file: https://github.com/haiwen/seahub/blob/21c827c68047e13700fe102d22a3f5515b22af89/seahub/settings.py#L484

xiez
  • 299
  • 3
  • 5
0

Time to add another one suggestion here, which worked for me. Django 3.2, but should work on any version.

What worked for me is assuming that the developers would be clever enough to output these to python stderr, not stdout. They were!

So..., just redirect stderr to via a standard bash 2>/dev/null

django-admin findstatic teststatic.css 2>/dev/null
Found 'teststatic.css' here:
  /Users/me/kds2/py2/bemyerp/websec/static/websec/nodelinks/teststatic.css
  /Users/me/kds2/py2/bemyerp/dist/teststatic.css

Of course, bear in mind your context and what this redirection does: suppressing ANY error message. For example, if django-admin is missing, that error message will also disappear (run missing-django-admin findstatic teststatic.css 2>/dev/null to see the effect).

what I was trying to filter out...

    HINT: Use django.db.models.JSONField instead.
pssystem.TagType: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
    HINT: Configure the DEFAULT_AUTO_FIELD setting or the AppConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.
Found 'teststatic.css' here:
  /Users/me/kds2/py2/bemyerp/websec/static/websec/nodelinks/teststatic.css
  /Users/me/kds2/py2/bemyerp/dist/teststatic.css

Things tried without success:

(I am not saying these never work, only that they didn't filter the particular messages I was getting and wanted to avoid, in my environment.

python -W ignore  manage.py findstatic teststatic.css
PYTHONWARNINGS=ignore django-admin findstatic teststatic.css
PYTHONWARNINGS=ignore python manage.py findstatic teststatic.css
python -Wd manage.py findstatic teststatic.css

env: Django 3.2, using Python 3.10 with virtualenv

JL Peyret
  • 10,917
  • 2
  • 54
  • 73