From 76e8d52397c84bcca74a34147cfdaf916904474c Mon Sep 17 00:00:00 2001
From: Oleg Girko
Date: Tue, 16 Aug 2022 16:10:47 +0300
Subject: [PATCH] Fix compatibility with Django 4.0.
Signed-off-by: Oleg Girko
---
.../protected_downloads/download/models.py | 4 ++--
examples/protected_downloads/download/urls.py | 10 ++++----
.../protected_downloads/download/views.py | 8 +++----
examples/protected_downloads/settings.py | 24 +++++++++++++++++--
examples/protected_downloads/urls.py | 10 ++++----
sendfile/__init__.py | 17 +++++++++----
sendfile/backends/_internalredirect.py | 6 ++++-
sendfile/backends/xsendfile.py | 3 ++-
sendfile/tests.py | 4 ++--
9 files changed, 59 insertions(+), 27 deletions(-)
diff --git a/examples/protected_downloads/download/models.py b/examples/protected_downloads/download/models.py
index 0e10dbc..24d2fcc 100644
--- a/examples/protected_downloads/download/models.py
+++ b/examples/protected_downloads/download/models.py
@@ -3,6 +3,7 @@
from django.contrib.auth.models import User
from django.conf import settings
from django.core.files.storage import FileSystemStorage
+from django.urls import reverse
sendfile_storage = FileSystemStorage(location=settings.SENDFILE_ROOT)
@@ -20,6 +21,5 @@ def is_user_allowed(self, user):
def __unicode__(self):
return self.title
- @models.permalink
def get_absolute_url(self):
- return ('download', [self.pk], {})
+ return reverse('download', args=[self.pk])
diff --git a/examples/protected_downloads/download/urls.py b/examples/protected_downloads/download/urls.py
index fd4bb28..a5b3240 100644
--- a/examples/protected_downloads/download/urls.py
+++ b/examples/protected_downloads/download/urls.py
@@ -1,8 +1,8 @@
-from django.conf.urls.defaults import *
+from django.urls import re_path
from .views import download, download_list
-urlpatterns = patterns('',
- url(r'^$', download_list),
- url(r'(?P\d+)/$', download, name='download'),
-)
+urlpatterns = [
+ re_path(r'^$', download_list),
+ re_path(r'(?P\d+)/$', download, name='download'),
+]
diff --git a/examples/protected_downloads/download/views.py b/examples/protected_downloads/download/views.py
index e99b6bc..8f5699a 100644
--- a/examples/protected_downloads/download/views.py
+++ b/examples/protected_downloads/download/views.py
@@ -1,5 +1,5 @@
from django.contrib.auth.decorators import login_required
-from django.shortcuts import get_object_or_404, render_to_response
+from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseForbidden
from django.db.models import Q
from django.template import RequestContext
@@ -29,6 +29,6 @@ def download_list(request):
downloads = downloads.filter(Q(is_public=True) | Q(users=request.user))
else:
downloads = downloads.filter(is_public=True)
- return render_to_response('download/download_list.html',
- {'download_list': downloads},
- context_instance=RequestContext(request))
+ return render(request, 'download/download_list.html',
+ {'download_list': downloads},
+ context_instance=RequestContext(request))
diff --git a/examples/protected_downloads/settings.py b/examples/protected_downloads/settings.py
index 245739c..183ae76 100644
--- a/examples/protected_downloads/settings.py
+++ b/examples/protected_downloads/settings.py
@@ -61,10 +61,29 @@
# 'django.template.loaders.eggs.load_template_source',
)
-MIDDLEWARE_CLASSES = (
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [
+ os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates')
+),
+ ],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ]
+ }
+ },
+]
+
+MIDDLEWARE = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'protected_downloads.urls'
@@ -79,7 +98,8 @@
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
- 'download',
+ 'django.contrib.messages',
+ 'protected_downloads.download',
'sendfile',
)
diff --git a/examples/protected_downloads/urls.py b/examples/protected_downloads/urls.py
index 238d8c7..dc39674 100644
--- a/examples/protected_downloads/urls.py
+++ b/examples/protected_downloads/urls.py
@@ -1,9 +1,9 @@
-from django.conf.urls.defaults import *
+from django.urls import include, re_path, path
from django.contrib import admin
admin.autodiscover()
-urlpatterns = patterns('',
- (r'^', include('protected_downloads.download.urls')),
- (r'^admin/', include(admin.site.urls)),
-)
+urlpatterns = [
+ path('admin/', admin.site.urls),
+ re_path(r'^', include('protected_downloads.download.urls')),
+]
diff --git a/sendfile/__init__.py b/sendfile/__init__.py
index 1cc9809..6048cb5 100644
--- a/sendfile/__init__.py
+++ b/sendfile/__init__.py
@@ -72,15 +72,22 @@ def sendfile(request, filename, attachment=False, attachment_filename=None, mime
parts = ['attachment']
if attachment_filename:
try:
- from django.utils.encoding import force_text
+ from django.utils.encoding import force_str as force_text
except ImportError:
- # Django 1.3
- from django.utils.encoding import force_unicode as force_text
+ # Django 2.x
+ try:
+ from django.utils.encoding import force_text
+ except ImportError:
+ # Django 1.3
+ from django.utils.encoding import force_unicode as force_text
attachment_filename = force_text(attachment_filename)
- ascii_filename = unicodedata.normalize('NFKD', attachment_filename).encode('ascii','ignore')
+ ascii_filename = force_text(unicodedata.normalize('NFKD', attachment_filename).encode('ascii','ignore'))
parts.append('filename="%s"' % ascii_filename)
if ascii_filename != attachment_filename:
- from django.utils.http import urlquote
+ try:
+ from urllib.parse import quote as urlquote
+ except ImportError:
+ from django.utils.http import urlquote
quoted_filename = urlquote(attachment_filename)
parts.append('filename*=UTF-8\'\'%s' % quoted_filename)
response['Content-Disposition'] = '; '.join(parts)
diff --git a/sendfile/backends/_internalredirect.py b/sendfile/backends/_internalredirect.py
index be4e069..e19cebf 100644
--- a/sendfile/backends/_internalredirect.py
+++ b/sendfile/backends/_internalredirect.py
@@ -1,7 +1,11 @@
import os.path
from django.conf import settings
-from django.utils.encoding import smart_text, smart_bytes
+from django.utils.encoding import smart_bytes
+try:
+ from django.utils.encoding import smart_str as smart_text
+except ImportError:
+ from django.utils.encoding import smart_text
try:
from urllib.parse import quote
diff --git a/sendfile/backends/xsendfile.py b/sendfile/backends/xsendfile.py
index a87aa83..e937e15 100644
--- a/sendfile/backends/xsendfile.py
+++ b/sendfile/backends/xsendfile.py
@@ -1,8 +1,9 @@
from django.http import HttpResponse
+from django.utils.encoding import force_str
def sendfile(request, filename, **kwargs):
response = HttpResponse()
- response['X-Sendfile'] = unicode(filename).encode('utf-8')
+ response['X-Sendfile'] = force_str(filename)
return response
diff --git a/sendfile/tests.py b/sendfile/tests.py
index 0643cae..aa8e186 100644
--- a/sendfile/tests.py
+++ b/sendfile/tests.py
@@ -132,7 +132,7 @@ def test_xaccelredirect_header_containing_unicode(self):
filepath = self.ensure_file(u'péter_là_gueule.txt')
response = real_sendfile(HttpRequest(), filepath)
self.assertTrue(response is not None)
- self.assertEqual(u'/private/péter_là_gueule.txt'.encode('utf-8'), unquote(response['X-Accel-Redirect']))
+ self.assertEqual(u'/private/péter_là_gueule.txt', unquote(response['X-Accel-Redirect']))
class TestModWsgiBackend(TempFileTestCase):
@@ -154,4 +154,4 @@ def test_location_header_containing_unicode(self):
filepath = self.ensure_file(u'péter_là_gueule.txt')
response = real_sendfile(HttpRequest(), filepath)
self.assertTrue(response is not None)
- self.assertEqual(u'/private/péter_là_gueule.txt'.encode('utf-8'), unquote(response['Location']))
+ self.assertEqual(u'/private/péter_là_gueule.txt', unquote(response['Location']))