Skip to content

Commit b96a8fd

Browse files
author
Ross Mechanic
authored
Added Django 3 and Python 3.8 support (#610)
* Added Django 3 and Python 3.8 support * Use django 3.0 release candidate to test on for now. will update when actual release is made * Updated flake8
1 parent e61cbaa commit b96a8fd

File tree

9 files changed

+182
-154
lines changed

9 files changed

+182
-154
lines changed

.travis.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@ python:
88
- 3.5
99
- 3.6
1010
- 3.7
11+
- 3.8
1112

1213
env:
1314
- DJANGO="Django>=1.11,<1.12"
1415
- DJANGO="Django>=2.0,<2.1"
1516
- DJANGO="Django>=2.1,<2.2"
1617
- DJANGO="Django>=2.2,<2.3"
18+
- DJANGO="Django==3.0rc1"
1719

1820
install:
1921
- pip install -U coverage codecov
20-
- pip install -U flake8==3.6.0
22+
- pip install -U flake8==3.7.9
2123
- pip install -U $DJANGO
2224
- if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then pip install black; fi
2325
- if [[ $TRAVIS_PYTHON_VERSION == '3.7' ]]; then pip install black; fi
@@ -31,15 +33,27 @@ script:
3133

3234
matrix:
3335
exclude:
36+
- python: 3.8
37+
env: DJANGO="Django>=1.11,<1.12"
3438
- python: 2.7
3539
env: DJANGO="Django>=2.0,<2.1"
40+
- python: 3.8
41+
env: DJANGO="Django>=2.0,<2.1"
3642
- python: 2.7
3743
env: DJANGO="Django>=2.1,<2.2"
3844
- python: 3.4
3945
env: DJANGO="Django>=2.1,<2.2"
46+
- python: 3.8
47+
env: DJANGO="Django>=2.1,<2.2"
4048
- python: 2.7
4149
env: DJANGO="Django>=2.2,<2.3"
4250
- python: 3.4
4351
env: DJANGO="Django>=2.2,<2.3"
52+
- python: 2.7
53+
env: DJANGO="Django==3.0rc1"
54+
- python: 3.4
55+
env: DJANGO="Django==3.0rc1"
56+
- python: 3.5
57+
env: DJANGO="Django==3.0rc1"
4458

4559
after_success: codecov

CHANGES.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Unreleased
99
- Fix `model_to_dict` to detect changes in a parent model when using
1010
`inherit=True` (backwards-incompatible for users who were directly
1111
using previous version) (gh-576)
12-
- Use an iterator for `clean_duplicate_history`
12+
- Use an iterator for `clean_duplicate_history` (gh-604)
13+
- Add support for Python 3.8 and Django 3.0 (gh-610)
1314

1415
2.7.3 (2019-07-15)
1516
------------------

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ This app supports the following combinations of Django and Python:
4040
1.11 2.7, 3.4, 3.5, 3.6, 3.7
4141
2.0 3.4, 3.5, 3.6, 3.7
4242
2.1 3.5, 3.6, 3.7
43-
2.2 3.5, 3.6, 3.7
43+
2.2 3.5, 3.6, 3.7, 3.8
44+
3.0 3.6, 3.7, 3.8
4445
========== =======================
4546

4647
Getting Help

docs/common_issues.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,8 @@ A few notes:
188188
Usage with django-modeltranslation
189189
----------------------------------
190190

191-
If you have ``django-modeltranslation`` installed, you will need to use the ``register()``
192-
method to model translation, as described `here`_.
193-
194-
.. _here https://github.com/treyhunner/django-simple-history/issues/209#issuecomment-181676111
191+
If you have ``django-modeltranslation`` installed, you will need to use the ``register()``
192+
method to model translation, as described `here <https://github.com/treyhunner/django-simple-history/issues/209#issuecomment-181676111>`__.
195193

196194

197195
Pointing to the model

setup.py

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,50 @@
33

44
tests_require = [
55
"Django>=1.11",
6-
"WebTest==2.0.24",
7-
"django-webtest==1.8.0",
86
"mock==1.0.1",
97
"six",
108
]
119

12-
setup(
13-
name="django-simple-history",
14-
version=simple_history.__version__,
15-
description="Store model history and view/revert changes from admin site.",
16-
long_description="\n".join((open("README.rst").read(), open("CHANGES.rst").read())),
17-
author="Corey Bertram",
18-
author_email="[email protected]",
19-
maintainer="Trey Hunner",
20-
url="https://github.com/treyhunner/django-simple-history",
21-
packages=[
22-
"simple_history",
23-
"simple_history.management",
24-
"simple_history.management.commands",
25-
"simple_history.templatetags",
26-
],
27-
classifiers=[
28-
"Development Status :: 5 - Production/Stable",
29-
"Framework :: Django",
30-
"Environment :: Web Environment",
31-
"Intended Audience :: Developers",
32-
"Framework :: Django",
33-
"Framework :: Django :: 1.11",
34-
"Framework :: Django :: 2.0",
35-
"Framework :: Django :: 2.1",
36-
"Framework :: Django :: 2.2",
37-
"Programming Language :: Python",
38-
"Programming Language :: Python :: 2.7",
39-
"Programming Language :: Python :: 3",
40-
"Programming Language :: Python :: 3.4",
41-
"Programming Language :: Python :: 3.5",
42-
"Programming Language :: Python :: 3.6",
43-
"Programming Language :: Python :: 3.7",
44-
"License :: OSI Approved :: BSD License",
45-
],
46-
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
47-
tests_require=tests_require,
48-
install_requires=["six"],
49-
include_package_data=True,
50-
test_suite="runtests.main",
51-
)
10+
with open("README.rst") as readme, open("CHANGES.rst") as changes:
11+
setup(
12+
name="django-simple-history",
13+
version=simple_history.__version__,
14+
description="Store model history and view/revert changes from admin site.",
15+
long_description="\n".join((readme.read(), changes.read())),
16+
author="Corey Bertram",
17+
author_email="[email protected]",
18+
maintainer="Trey Hunner",
19+
url="https://github.com/treyhunner/django-simple-history",
20+
packages=[
21+
"simple_history",
22+
"simple_history.management",
23+
"simple_history.management.commands",
24+
"simple_history.templatetags",
25+
],
26+
classifiers=[
27+
"Development Status :: 5 - Production/Stable",
28+
"Framework :: Django",
29+
"Environment :: Web Environment",
30+
"Intended Audience :: Developers",
31+
"Framework :: Django",
32+
"Framework :: Django :: 1.11",
33+
"Framework :: Django :: 2.0",
34+
"Framework :: Django :: 2.1",
35+
"Framework :: Django :: 2.2",
36+
"Framework :: Django :: 3.0",
37+
"Programming Language :: Python",
38+
"Programming Language :: Python :: 2.7",
39+
"Programming Language :: Python :: 3",
40+
"Programming Language :: Python :: 3.4",
41+
"Programming Language :: Python :: 3.5",
42+
"Programming Language :: Python :: 3.6",
43+
"Programming Language :: Python :: 3.7",
44+
"Programming Language :: Python :: 3.8",
45+
"License :: OSI Approved :: BSD License",
46+
],
47+
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
48+
tests_require=tests_require,
49+
install_requires=["six"],
50+
include_package_data=True,
51+
test_suite="runtests.main",
52+
)

simple_history/admin.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import unicode_literals
22

3+
import django
34
from django import http
45
from django.conf import settings
56
from django.conf.urls import url
@@ -10,13 +11,18 @@
1011
from django.core.exceptions import PermissionDenied
1112
from django.shortcuts import get_object_or_404, render
1213
from django.urls import reverse
13-
from django.utils.encoding import force_text
1414
from django.utils.html import mark_safe
1515
from django.utils.text import capfirst
16-
from django.utils.translation import ugettext as _
1716

1817
from . import utils
1918

19+
if django.VERSION < (2,):
20+
from django.utils.encoding import force_text as force_str
21+
from django.utils.translation import ugettext as _
22+
else:
23+
from django.utils.encoding import force_str
24+
from django.utils.translation import gettext as _
25+
2026
USER_NATURAL_KEY = tuple(key.lower() for key in settings.AUTH_USER_MODEL.split(".", 1))
2127

2228
SIMPLE_HISTORY_EDIT = getattr(settings, "SIMPLE_HISTORY_EDIT", False)
@@ -80,9 +86,9 @@ def history_view(self, request, object_id, extra_context=None):
8086
content_type.model,
8187
)
8288
context = {
83-
"title": _("Change history: %s") % force_text(obj),
89+
"title": _("Change history: %s") % force_str(obj),
8490
"action_list": action_list,
85-
"module_name": capfirst(force_text(opts.verbose_name_plural)),
91+
"module_name": capfirst(force_str(opts.verbose_name_plural)),
8692
"object": obj,
8793
"root_path": getattr(self.admin_site, "root_path", None),
8894
"app_label": app_label,
@@ -102,8 +108,8 @@ def response_change(self, request, obj):
102108
verbose_name = obj._meta.verbose_name
103109

104110
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {
105-
"name": force_text(verbose_name),
106-
"obj": force_text(obj),
111+
"name": force_str(verbose_name),
112+
"obj": force_str(obj),
107113
}
108114

109115
self.message_user(
@@ -167,7 +173,7 @@ def history_form_view(self, request, object_id, version_id, extra_context=None):
167173
model_name = original_opts.model_name
168174
url_triplet = self.admin_site.name, original_opts.app_label, model_name
169175
context = {
170-
"title": _("Revert %s") % force_text(obj),
176+
"title": _("Revert %s") % force_str(obj),
171177
"adminform": admin_form,
172178
"object_id": object_id,
173179
"original": obj,

simple_history/models.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,36 @@
22

33
import copy
44
import importlib
5-
import six
65
import threading
76
import uuid
87
import warnings
98

9+
import django
10+
import six
1011
from django.apps import apps
1112
from django.conf import settings
1213
from django.contrib import admin
1314
from django.contrib.auth import get_user_model
1415
from django.core.exceptions import ObjectDoesNotExist
15-
from django.core.serializers import serialize
1616
from django.db import models
1717
from django.db.models import Q
1818
from django.db.models.fields.proxy import OrderWrt
1919
from django.forms.models import model_to_dict
2020
from django.urls import reverse
21-
from django.utils.encoding import python_2_unicode_compatible, smart_text
2221
from django.utils.text import format_lazy
2322
from django.utils.timezone import now
24-
from django.utils.translation import ugettext_lazy as _
25-
2623
from simple_history import utils
2724
from . import exceptions
2825
from .manager import HistoryDescriptor
2926
from .signals import post_create_historical_record, pre_create_historical_record
3027

31-
import json
28+
if django.VERSION < (2,):
29+
from django.utils.translation import ugettext_lazy as _
30+
from django.utils.encoding import smart_text as smart_str
31+
from django.utils.encoding import python_2_unicode_compatible
32+
else:
33+
from django.utils.translation import gettext_lazy as _
34+
from django.utils.encoding import smart_str
3235

3336
registered_models = {}
3437

@@ -223,7 +226,12 @@ def create_history_model(self, model, inherited):
223226
name = self.get_history_model_name(model)
224227

225228
registered_models[model._meta.db_table] = model
226-
return python_2_unicode_compatible(type(str(name), self.bases, attrs))
229+
history_model = type(str(name), self.bases, attrs)
230+
return (
231+
python_2_unicode_compatible(history_model)
232+
if django.VERSION < (2,)
233+
else history_model
234+
)
227235

228236
def fields_included(self, model):
229237
fields = []
@@ -448,7 +456,7 @@ def get_meta_options(self, model):
448456
if self.user_set_verbose_name:
449457
name = self.user_set_verbose_name
450458
else:
451-
name = format_lazy("historical {}", smart_text(model._meta.verbose_name))
459+
name = format_lazy("historical {}", smart_str(model._meta.verbose_name))
452460
meta_fields["verbose_name"] = name
453461
if self.app:
454462
meta_fields["app_label"] = self.app

0 commit comments

Comments
 (0)