Skip to content

Commit d1bc0b4

Browse files
authored
Merge pull request #23 from maykinmedia/feature/fix-export
🐛 fix export action exception
2 parents c42f78c + e829fff commit d1bc0b4

File tree

10 files changed

+124
-41
lines changed

10 files changed

+124
-41
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Tests and PyPI publishing
33
on:
44
push:
55
branches:
6-
- main
6+
- master
77
tags:
88
- '*'
99
pull_request:
@@ -16,12 +16,16 @@ jobs:
1616
strategy:
1717
matrix:
1818
python: ["3.8", "3.9", "3.10", "3.11", "3.12"]
19-
django: ["3.2", "4.2"]
19+
django: ["3.2", "4.2", "5.2"]
2020
exclude:
2121
- python: "3.11"
2222
django: "3.2"
2323
- python: "3.12"
2424
django: "3.2"
25+
- python: "3.8"
26+
django: "5.2"
27+
- python: "3.9"
28+
django: "5.2"
2529

2630
steps:
2731
- uses: actions/checkout@v4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,6 @@ venv.bak/
104104

105105
# mypy
106106
.mypy_cache/
107+
108+
# JetBrains
109+
.idea/

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ classifiers = [
1717
"Framework :: Django",
1818
"Framework :: Django :: 3.2",
1919
"Framework :: Django :: 4.2",
20+
"Framework :: Django :: 5.2",
2021
"Intended Audience :: Developers",
2122
"Operating System :: Unix",
2223
"Operating System :: MacOS",

regex_redirects/actions.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,15 @@ def export_as_csv(modeladmin, request, queryset):
3232
field_names = field_names - excludeset
3333

3434
response = HttpResponse(content_type="text/csv")
35-
response["Content-Disposition"] = "attachment; filename=%s.csv" % opts.replace(
36-
".", "_"
35+
response["Content-Disposition"] = (
36+
"attachment; filename=%s.csv" % opts.model_name.replace(".", "_")
3737
)
3838

3939
writer = csv.writer(response)
4040
if header:
4141
writer.writerow(list(field_names))
4242
for obj in queryset:
43-
writer.writerow(
44-
[
45-
getattr(obj, field).encode("utf-8", "replace")
46-
for field in field_names
47-
]
48-
)
43+
writer.writerow([getattr(obj, field) for field in field_names])
4944
return response
5045

5146
export_as_csv.short_description = description

regex_redirects/tests.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
from django.contrib.auth.models import User
12
from django.core.cache import cache
23
from django.test import TestCase
34
from django.test.utils import override_settings
5+
from django.urls import reverse
46

57
from .middleware import (
68
DJANGO_REGEX_REDIRECTS_CACHE_KEY,
@@ -149,3 +151,35 @@ def test_fallback_redirects(self):
149151
status_code=301,
150152
target_status_code=404,
151153
)
154+
155+
156+
class RedirectExportAdminActionTest(TestCase):
157+
158+
def setUp(self):
159+
160+
self.superuser = User.objects.create_superuser("exporter_man")
161+
self.client.force_login(self.superuser)
162+
163+
self.redirect_1 = Redirect.objects.create(
164+
old_path="/initial", new_path="/new_target"
165+
)
166+
self.redirect_2 = Redirect.objects.create(
167+
old_path=r"/news/index/(\d+)/(.*)/",
168+
new_path="/my/news/$2/",
169+
regular_expression=True,
170+
)
171+
172+
self.url = reverse("admin:regex_redirects_redirect_changelist")
173+
174+
def test_simple(self):
175+
data = {
176+
"action": "export_as_csv",
177+
"_selected_action": [self.redirect_1.pk, self.redirect_2.pk],
178+
}
179+
180+
response = self.client.post(self.url, data)
181+
182+
self.assertEqual(response.status_code, 200)
183+
self.assertEqual(
184+
response.get("Content-Disposition"), "attachment; filename=redirect.csv"
185+
)

testapp/__init__.py

Whitespace-only changes.

testapp/settings.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from pathlib import Path
2+
3+
BASE_DIR = Path(__file__).resolve(strict=True).parent
4+
5+
SECRET_KEY = "so-secret-i-cant-believe-you-are-looking-at-this"
6+
7+
USE_TZ = True
8+
9+
DEBUG = True
10+
11+
APPEND_SLASH = False
12+
13+
SITE_ID = 1
14+
15+
ALLOWED_HOSTS = [
16+
"example.com",
17+
]
18+
19+
DATABASES = {
20+
"default": {
21+
"ENGINE": "django.db.backends.sqlite3",
22+
"NAME": BASE_DIR / "regex_redirects.db",
23+
}
24+
}
25+
26+
INSTALLED_APPS = [
27+
"django.contrib.contenttypes",
28+
"django.contrib.auth",
29+
"django.contrib.sessions",
30+
"django.contrib.sites",
31+
"django.contrib.messages",
32+
"django.contrib.admin",
33+
"regex_redirects",
34+
"testapp",
35+
]
36+
37+
MIDDLEWARE = [
38+
"django.middleware.security.SecurityMiddleware",
39+
"django.contrib.sessions.middleware.SessionMiddleware",
40+
"django.middleware.common.CommonMiddleware",
41+
"django.middleware.csrf.CsrfViewMiddleware",
42+
"django.contrib.auth.middleware.AuthenticationMiddleware",
43+
"django.contrib.messages.middleware.MessageMiddleware",
44+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
45+
"regex_redirects.middleware.RedirectFallbackMiddleware",
46+
]
47+
48+
TEMPLATES = [
49+
{
50+
"BACKEND": "django.template.backends.django.DjangoTemplates",
51+
"DIRS": [],
52+
"APP_DIRS": True,
53+
"OPTIONS": {
54+
"context_processors": [
55+
"django.template.context_processors.debug",
56+
"django.template.context_processors.request",
57+
"django.contrib.auth.context_processors.auth",
58+
"django.contrib.messages.context_processors.messages",
59+
],
60+
},
61+
},
62+
]
63+
64+
ROOT_URLCONF = "testapp.urls"

testapp/urls.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.contrib import admin
2+
from django.urls import path
3+
4+
urlpatterns = [
5+
path("admin/", admin.site.urls),
6+
]

testsettings.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

tox.ini

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[tox]
22
envlist =
33
py{38,39,310}-django{32,42}
4-
py3{11,12}-django{41,42}
4+
py310-django52
5+
py3{11,12}-django{41,42,52}
56
isort
67
black
78
flake8
@@ -19,11 +20,15 @@ python =
1920
DJANGO =
2021
3.2: django32
2122
4.2: django42
23+
5.2: django52
2224

2325
[testenv]
26+
setenv =
27+
DJANGO_SETTINGS_MODULE=testapp.settings
2428
deps=
2529
django32: Django~=3.2.0
2630
django42: Django~=4.2.0
31+
django52: Django~=5.2.0
2732
commands =
2833
python manage.py test regex_redirects
2934

@@ -35,7 +40,7 @@ commands = isort --check-only --diff .
3540
[testenv:black]
3641
extras = tests
3742
skipsdist = True
38-
commands = black --check regex_redirects testsettings.py manage.py
43+
commands = black --check regex_redirects testapp manage.py
3944

4045
[testenv:flake8]
4146
extras = tests

0 commit comments

Comments
 (0)