diff --git a/.travis.yml b/.travis.yml
index 5c279577..3c0ca8ac 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,14 @@ matrix:
     python: '3.7'
   - env: TOXENV=py38-django30
     python: '3.8'
+  - env: TOXENV=pypy3-django31
+    python: pypy3
+  - env: TOXENV=py36-django31
+    python: '3.6'
+  - env: TOXENV=py37-django31
+    python: '3.7'
+  - env: TOXENV=py38-django31
+    python: '3.8'
   - env: TOXENV=py36-django-master
     python: '3.6'
   - env: TOXENV=py37-django-master
diff --git a/HISTORY.rst b/HISTORY.rst
index fe55493f..c979f1f3 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -3,6 +3,17 @@
 History
 =======
 
+2.0.5
+======
+
+* Adding **Django 3.1** compatibility.
+* CachedStaticFilesStorage is removed from Django. Add a check
+  of the current version to prevent error while importing. Thank to @vmsp
+* Context in django.template.base is removed from Django and
+  not used anymore in django-pipeline.
+* Fixing widgets tests of django-pipeline due to Media.render_js change in 
+  Django. More information in Django ticket #31892
+
 2.0.4
 ======
 
diff --git a/pipeline/storage.py b/pipeline/storage.py
index a7fed8c3..0ea6f42c 100644
--- a/pipeline/storage.py
+++ b/pipeline/storage.py
@@ -2,9 +2,9 @@
 
 from io import BytesIO
 
-import django
+from django import get_version as django_version
 
-_CACHED_STATIC_FILES_STORAGE_AVAILABLE = django.VERSION[0] <= 3 and django.VERSION[1] < 1
+_CACHED_STATIC_FILES_STORAGE_AVAILABLE = django_version() < '3.1'
 
 if _CACHED_STATIC_FILES_STORAGE_AVAILABLE:
     from django.contrib.staticfiles.storage import CachedStaticFilesStorage
diff --git a/pipeline/templatetags/pipeline.py b/pipeline/templatetags/pipeline.py
index bb9e1ff5..74451f78 100644
--- a/pipeline/templatetags/pipeline.py
+++ b/pipeline/templatetags/pipeline.py
@@ -4,7 +4,6 @@
 from django.contrib.staticfiles.storage import staticfiles_storage
 
 from django import template
-from django.template.context import Context
 from django.template.base import VariableDoesNotExist
 from django.template.loader import render_to_string
 from django.utils.safestring import mark_safe
diff --git a/setup.py b/setup.py
index bb2cee98..9042e430 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@
 
 setup(
     name='django-pipeline',
-    version='2.0.4',
+    version='2.0.5',
     description='Pipeline is an asset packaging library for Django.',
     long_description=io.open('README.rst', encoding='utf-8').read() + '\n\n' +
         io.open('HISTORY.rst', encoding='utf-8').read(),
@@ -25,6 +25,7 @@
         'Framework :: Django',
         'Framework :: Django :: 2.2',
         'Framework :: Django :: 3.0',
+        'Framework :: Django :: 3.1',
         'Intended Audience :: Developers',
         'License :: OSI Approved :: MIT License',
         'Operating System :: OS Independent',
diff --git a/tests/tests/test_forms.py b/tests/tests/test_forms.py
index 78abca5f..58234b40 100644
--- a/tests/tests/test_forms.py
+++ b/tests/tests/test_forms.py
@@ -1,3 +1,4 @@
+from django import get_version as django_version
 from django.forms import Media
 from django.test import TestCase
 
@@ -147,6 +148,7 @@ class MyMedia(PipelineFormMedia):
             js = ('extra1.js', 'extra2.js')
 
         media = Media(MyMedia)
+        script_tag = '<script type="text/javascript" src="%s"></script>' if django_version() < '3.1' else '<script src="%s"></script>'
 
         self.assertEqual(
             MyMedia.js,
@@ -160,7 +162,7 @@ class MyMedia(PipelineFormMedia):
         self.assertEqual(
             media.render_js(),
             [
-                '<script type="text/javascript" src="%s"></script>' % path
+                script_tag % path
                 for path in (
                     '/static/extra1.js',
                     '/static/extra2.js',
@@ -177,6 +179,7 @@ class MyMedia(PipelineFormMedia):
             js = ('extra1.js', 'extra2.js')
 
         media = Media(MyMedia)
+        script_tag = '<script type="text/javascript" src="%s"></script>' if django_version() < '3.1' else '<script src="%s"></script>'
 
         self.assertEqual(
             MyMedia.js,
@@ -191,7 +194,7 @@ class MyMedia(PipelineFormMedia):
         self.assertEqual(
             media.render_js(),
             [
-                '<script type="text/javascript" src="%s"></script>' % path
+                script_tag % path
                 for path in (
                     '/static/extra1.js',
                     '/static/extra2.js',
diff --git a/tox.ini b/tox.ini
index 16ce68f6..952e3ae5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,9 @@
 [tox]
 envlist =
-  pypy3-django{22,30}
-  py36-django{22,30,-master}
-  py37-django{22,30,-master}
-  py38-django{22,30,-master}
+  pypy3-django{22,30,31}
+  py36-django{22,30,31,-master}
+  py37-django{22,30,31,-master}
+  py38-django{22,30,31,-master}
   docs
 
 [testenv]
@@ -16,6 +16,7 @@ deps =
   pypy3: mock
   django22: Django>=2.2.1,<2.3
   django30: Django>=3.0,<3.1
+  django31: Django>=3.1,<3.2
   django-master: https://github.com/django/django/archive/master.tar.gz
   jinja2
   coverage