diff --git a/.travis.yml b/.travis.yml
index 0bfac07..68bf21c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,34 +4,23 @@ cache:
directories:
- "~/.cache/pip"
python:
-- '2.7'
+- '3.8'
+- '3.7'
- '3.6'
- '3.5'
env:
-- DJANGO=2.0
-- DJANGO=2.1
-- DJANGO=1.11
+- DJANGO=2.2
+- DJANGO=3.0
+- DJANGO=3.1
- DJANGO=master
-matrix:
+jobs:
exclude:
- - python: '2.7'
- env: DJANGO=master
- - python: '2.7'
- env: DJANGO=2.0
- - python: '2.7'
- env: DJANGO=2.1
- - python: '3.6'
- env: DJANGO=1.11
- allow_failures:
+ - python: '3.5'
+ env: DJANGO=3.0
+ - python: '3.5'
+ env: DJANGO=3.1
- python: '3.5'
env: DJANGO=master
- - python: '3.6'
- env: DJANGO=master
- - python: '3.5'
- env: DJANGO=2.1
- - python: '3.6'
- env: DJANGO=2.1
-
install:
- pip install tox
script:
@@ -46,5 +35,5 @@ deploy:
tags: true
repo: jazzband/django-admin2
# only do the PyPI release for exactly one scenario of the test matrix:
- condition: "$DJANGO = 1.11"
+ condition: "$DJANGO = 2.2"
python: 3.6
diff --git a/djadmin2/__init__.py b/djadmin2/__init__.py
index 76f005e..f2e16b2 100644
--- a/djadmin2/__init__.py
+++ b/djadmin2/__init__.py
@@ -1,7 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
-
__version__ = '0.7.1'
__author__ = 'Daniel Greenfeld & Contributors'
diff --git a/djadmin2/actions.py b/djadmin2/actions.py
index 9638726..b78a8c3 100644
--- a/djadmin2/actions.py
+++ b/djadmin2/actions.py
@@ -1,12 +1,9 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
from django.contrib import messages
from django.db import router
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.text import capfirst
from django.utils.translation import ugettext as _
-from django.utils.translation import ugettext_lazy, ungettext, pgettext_lazy
+from django.utils.translation import gettext_lazy, ngettext, pgettext_lazy
from django.views.generic import TemplateView
from . import permissions, utils
@@ -26,7 +23,7 @@ class BaseListAction(Admin2ModelMixin, TemplateView):
permission_classes = (permissions.IsStaffPermission,)
- empty_message = ugettext_lazy(
+ empty_message = gettext_lazy(
'Items must be selected in order to perform actions '
'on them. No items have been changed.'
)
@@ -50,7 +47,7 @@ class BaseListAction(Admin2ModelMixin, TemplateView):
objects_name = options.verbose_name
else:
objects_name = options.verbose_name_plural
- self.objects_name = force_text(objects_name)
+ self.objects_name = force_str(objects_name)
super(BaseListAction, self).__init__(*args, **kwargs)
@@ -92,8 +89,8 @@ class BaseListAction(Admin2ModelMixin, TemplateView):
def _format_callback(obj):
opts = utils.model_options(obj)
- return '%s: %s' % (force_text(capfirst(opts.verbose_name)),
- force_text(obj))
+ return '%s: %s' % (force_str(capfirst(opts.verbose_name)),
+ force_str(obj))
using = router.db_for_write(self.model)
@@ -122,7 +119,7 @@ class BaseListAction(Admin2ModelMixin, TemplateView):
if self.process_queryset() is None:
# objects_name should already be pluralized, see __init__
- message = ungettext(
+ message = ngettext(
self.success_message,
self.success_message_plural,
self.item_count
@@ -146,7 +143,7 @@ class DeleteSelectedAction(BaseListAction):
default_template_name = "actions/delete_selected_confirmation.html"
- description = ugettext_lazy("Delete selected items")
+ description = gettext_lazy("Delete selected items")
success_message = pgettext_lazy(
'singular form',
diff --git a/djadmin2/admin2.py b/djadmin2/admin2.py
index abbba0a..90f7633 100644
--- a/djadmin2/admin2.py
+++ b/djadmin2/admin2.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
from django.conf import settings
from django.contrib.auth.models import Group, User
from django.contrib.sites.models import Site
diff --git a/djadmin2/apiviews.py b/djadmin2/apiviews.py
index 1a11059..513e880 100644
--- a/djadmin2/apiviews.py
+++ b/djadmin2/apiviews.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
from django.utils.encoding import force_str
from rest_framework import fields, generics, serializers
from rest_framework.response import Response
diff --git a/djadmin2/apps.py b/djadmin2/apps.py
index c991a04..eb42c75 100644
--- a/djadmin2/apps.py
+++ b/djadmin2/apps.py
@@ -1,6 +1,6 @@
from django.apps import AppConfig
from django.db.models.signals import post_migrate
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from djadmin2.permissions import create_view_permissions
diff --git a/djadmin2/core.py b/djadmin2/core.py
index bf04d9d..790d581 100644
--- a/djadmin2/core.py
+++ b/djadmin2/core.py
@@ -1,10 +1,7 @@
-# -*- coding: utf-8 -*-:
"""
WARNING: This file about to undergo major refactoring by @pydanny per
Issue #99.
"""
-from __future__ import division, absolute_import, unicode_literals
-
from importlib import import_module
from django.conf import settings
diff --git a/djadmin2/filters.py b/djadmin2/filters.py
index 6eeb58a..54b87bd 100644
--- a/djadmin2/filters.py
+++ b/djadmin2/filters.py
@@ -1,18 +1,14 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
-import collections
+import collections.abc
from itertools import chain
import django_filters
from django import forms
from django.forms import widgets as django_widgets
from django.forms.utils import flatatt
-from django.utils import six
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from django.utils.html import format_html
from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy
+from django.utils.translation import gettext_lazy
from .utils import type_str
@@ -33,7 +29,7 @@ class ChoicesAsLinksWidget(django_widgets.Select):
for choice_value, choice_label in chain(self.choices, choices):
links.append(format_html(
LINK_TEMPLATE,
- name, choice_value, flatatt(attrs), force_text(choice_label),
+ name, choice_value, flatatt(attrs), force_str(choice_label),
))
return mark_safe(u"
".join(links))
@@ -45,9 +41,9 @@ class NullBooleanLinksWidget(
def __init__(self, attrs=None, choices=()):
super(ChoicesAsLinksWidget, self).__init__(attrs)
self.choices = [
- ('1', ugettext_lazy('Unknown')),
- ('2', ugettext_lazy('Yes')),
- ('3', ugettext_lazy('No')),
+ ('1', gettext_lazy('Unknown')),
+ ('2', gettext_lazy('Yes')),
+ ('3', gettext_lazy('No')),
]
@@ -70,7 +66,7 @@ def build_list_filter(request, model_admin, queryset):
`request.GET` and `queryset`.
"""
# if ``list_filter`` is not iterable return it right away
- if not isinstance(model_admin.list_filter, collections.Iterable):
+ if not isinstance(model_admin.list_filter, collections.abc.Iterable):
return model_admin.list_filter(
request.GET,
queryset=queryset,
@@ -78,7 +74,7 @@ def build_list_filter(request, model_admin, queryset):
# otherwise build :mod:`django_filters.FilterSet`
filters = []
for field_filter in model_admin.list_filter:
- if isinstance(field_filter, six.string_types):
+ if isinstance(field_filter, str):
filters.append(get_filter_for_field_name(
queryset.model,
field_filter,
@@ -135,8 +131,9 @@ def get_filter_for_field_name(model, field_name):
django_filters.filterset.get_model_field(model, field_name,),
field_name,
)
+ print("EXTRA!!!!")
+ print(filter_.extra)
filter_.widget = FILTER_TYPE_TO_WIDGET.get(
- filter_.__class__,
- filter_.widget,
+ filter_.__class__
)
return filter_
diff --git a/djadmin2/forms.py b/djadmin2/forms.py
index d8279f7..a1b9f66 100644
--- a/djadmin2/forms.py
+++ b/djadmin2/forms.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.forms import AuthenticationForm
@@ -8,7 +5,7 @@ from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.core.exceptions import ValidationError
from django.urls import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
# Translators : %(username)s will be replaced by the username_field name
diff --git a/djadmin2/migrations/0001_initial.py b/djadmin2/migrations/0001_initial.py
index f3030bc..b94961b 100644
--- a/djadmin2/migrations/0001_initial.py
+++ b/djadmin2/migrations/0001_initial.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
from django.db import migrations, models
from django.conf import settings
diff --git a/djadmin2/models.py b/djadmin2/models.py
index ba10270..b48d7d3 100644
--- a/djadmin2/models.py
+++ b/djadmin2/models.py
@@ -1,14 +1,10 @@
-# -*- coding: utf-8 -*-
""" Boilerplate for now, will serve a purpose soon! """
-from __future__ import division, absolute_import, unicode_literals
-
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db import models
-from django.utils.encoding import force_text
-from django.utils.encoding import python_2_unicode_compatible
+from django.utils.encoding import force_str
from django.utils.encoding import smart_text
-from django.utils.translation import ugettext, ugettext_lazy as _
+from django.utils.translation import ugettext, gettext_lazy as _
from .utils import quote
@@ -17,12 +13,11 @@ class LogEntryManager(models.Manager):
def log_action(self, user_id, obj, action_flag, change_message=''):
content_type_id = ContentType.objects.get_for_model(obj).id
e = self.model(None, None, user_id, content_type_id,
- smart_text(obj.id), force_text(obj)[:200],
+ smart_text(obj.id), force_str(obj)[:200],
action_flag, change_message)
e.save()
-@python_2_unicode_compatible
class LogEntry(models.Model):
ADDITION = 1
CHANGE = 2
diff --git a/djadmin2/permissions.py b/djadmin2/permissions.py
index 200fc3f..fbeb00b 100644
--- a/djadmin2/permissions.py
+++ b/djadmin2/permissions.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
"""
djadmin2's permission handling. The permission classes have the same API as
the permission handling classes of the django-rest-framework. That way, we can
@@ -15,8 +14,6 @@ interface:
The permission classes are then just fancy wrappers of these basic checks of
which it can hold multiple.
"""
-from __future__ import division, absolute_import, unicode_literals
-
import logging
import re
@@ -25,8 +22,7 @@ from django.db.utils import DEFAULT_DB_ALIAS
from django.apps import apps
from django.core.exceptions import ValidationError
from django.db import router
-from django.utils import six
-from django.utils.encoding import python_2_unicode_compatible, force_text
+from django.utils.encoding import force_str
logger = logging.getLogger('djadmin2')
@@ -191,7 +187,6 @@ class ModelDeletePermission(BasePermission):
permissions = (model_permission('{app_label}.delete_{model_name}'),)
-@python_2_unicode_compatible
class TemplatePermissionChecker(object):
'''
Can be used in the template like:
@@ -286,7 +281,7 @@ class TemplatePermissionChecker(object):
Return a clone of the permission wrapper with a new model_admin bind
to it.
'''
- if isinstance(admin, six.string_types):
+ if isinstance(admin, str):
try:
admin = self._model_admin.admin.get_admin_by_name(admin)
except ValueError:
@@ -300,7 +295,7 @@ class TemplatePermissionChecker(object):
'''
Return a clone of the permission wrapper with a new view bind to it.
'''
- if isinstance(view, six.string_types):
+ if isinstance(view, str):
if view not in self.view_name_mapping:
return ''
view_name = self.view_name_mapping[view]
@@ -365,7 +360,7 @@ class TemplatePermissionChecker(object):
def __str__(self):
if self._view is None:
return ''
- return force_text(bool(self))
+ return force_str(bool(self))
def create_view_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs): # noqa
diff --git a/djadmin2/renderers.py b/djadmin2/renderers.py
index 614528f..52e8547 100644
--- a/djadmin2/renderers.py
+++ b/djadmin2/renderers.py
@@ -1,17 +1,14 @@
-# -*- coding: utf-8 -*-
"""
There are currently a few renderers that come directly with django-admin2. They
are used by default for some field types.
"""
-from __future__ import division, absolute_import, unicode_literals
-
import os.path
from datetime import date, time, datetime
from django.db import models
from django.template.loader import render_to_string
from django.utils import formats, timezone
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from djadmin2 import settings
@@ -65,7 +62,7 @@ def title_renderer(value, field):
:rtype: unicode or str
"""
- return force_text(value).title()
+ return force_str(value).title()
def number_renderer(value, field):
diff --git a/djadmin2/settings.py b/djadmin2/settings.py
index 0d90930..5960443 100644
--- a/djadmin2/settings.py
+++ b/djadmin2/settings.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
from django.conf import settings
diff --git a/djadmin2/templatetags/admin2_tags.py b/djadmin2/templatetags/admin2_tags.py
index 7625ed7..0595cb1 100644
--- a/djadmin2/templatetags/admin2_tags.py
+++ b/djadmin2/templatetags/admin2_tags.py
@@ -1,11 +1,8 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
from numbers import Number
from datetime import date, time, datetime
from django import template
-from django.db.models.fields import FieldDoesNotExist
+from django.core.exceptions import FieldDoesNotExist
from .. import utils, renderers, models, settings
diff --git a/djadmin2/tests/migrations/0001_initial.py b/djadmin2/tests/migrations/0001_initial.py
index 700cd16..90601fd 100644
--- a/djadmin2/tests/migrations/0001_initial.py
+++ b/djadmin2/tests/migrations/0001_initial.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
from django.db import migrations, models
diff --git a/djadmin2/tests/test_renderers.py b/djadmin2/tests/test_renderers.py
index 3e53b20..163e052 100644
--- a/djadmin2/tests/test_renderers.py
+++ b/djadmin2/tests/test_renderers.py
@@ -1,11 +1,7 @@
-# -*- coding: utf-8 -*-
-from __future__ import division, absolute_import, unicode_literals
-
import datetime as dt
from decimal import Decimal
from django.test import TestCase
-from django.utils import six
from django.utils.translation import activate
from .. import renderers
@@ -106,10 +102,7 @@ class NumberRendererTest(TestCase):
def testEndlessFloat(self):
out = self.renderer(1.0 / 3, None)
- if six.PY2:
- self.assertEqual('0.333333333333', out)
- else:
- self.assertEqual('0.3333333333333333', out)
+ self.assertEqual('0.3333333333333333', out)
def testPlainDecimal(self):
number = '0.123456789123456789123456789'
diff --git a/djadmin2/tests/test_utils.py b/djadmin2/tests/test_utils.py
index d54f43b..1264b82 100644
--- a/djadmin2/tests/test_utils.py
+++ b/djadmin2/tests/test_utils.py
@@ -1,5 +1,4 @@
from django.test import TestCase
-from django.utils import six
from .. import utils
from ..views import IndexView
@@ -137,16 +136,10 @@ class UtilsTest(TestCase):
def __unicode__(self):
return "unicode"
- if six.PY2:
- self.assertEqual(
- utils.get_attr(Klass(), "__str__"),
- "unicode"
- )
- else:
- self.assertEqual(
- utils.get_attr(Klass(), "__str__"),
- "str"
- )
+ self.assertEqual(
+ utils.get_attr(Klass(), "__str__"),
+ "str"
+ )
def test_get_attr(self):
class Klass(object):
diff --git a/djadmin2/tests/test_views.py b/djadmin2/tests/test_views.py
index 273510b..604b965 100644
--- a/djadmin2/tests/test_views.py
+++ b/djadmin2/tests/test_views.py
@@ -1,7 +1,7 @@
from django.test import TestCase, override_settings
from django.urls import reverse
-from django.utils.encoding import force_text
+from django.utils.encoding import force_str
from .. import views
@@ -27,4 +27,4 @@ class CustomLoginViewTest(TestCase):
def test_view_ok(self):
response = self.client.get(reverse("admin2:dashboard"))
- self.assertInHTML('
Are you sure you want to delete the selected post? The following item will be deleted:
', force_text(response.content)) + 'Are you sure you want to delete the selected post? The following item will be deleted:
', force_str(response.content)) def test_delete_selected_post_confirmation(self): post = Post.objects.create(title="A Post Title", body="body") @@ -331,7 +328,7 @@ class PostListTestCustomAction(BaseIntegrationTest): def test_publish_action_displayed_in_list(self): response = self.client.get(reverse("admin2:blog_post_index")) self.assertInHTML( - 'Publish selected items', force_text(response.content)) + 'Publish selected items', force_str(response.content)) def test_publish_selected_items(self): post = Post.objects.create(title="A Post Title", @@ -350,7 +347,7 @@ class PostListTestCustomAction(BaseIntegrationTest): def test_unpublish_action_displayed_in_list(self): response = self.client.get(reverse("admin2:blog_post_index")) self.assertInHTML( - 'Unpublish selected items', force_text(response.content)) + 'Unpublish selected items', force_str(response.content)) def test_unpublish_selected_items(self): post = Post.objects.create(title="A Post Title", @@ -380,7 +377,7 @@ class PostCreateViewTest(BaseIntegrationTest): def test_view_ok(self): response = self.client.get(reverse("admin2:blog_post_create")) self.assertNotIn( - '''enctype="multipart/form-data"''', force_text(response.content)) + '''enctype="multipart/form-data"''', force_str(response.content)) self.assertEqual(response.status_code, 200) def test_create_post(self): diff --git a/example/example/urls.py b/example/example/urls.py index eb45787..21655bb 100644 --- a/example/example/urls.py +++ b/example/example/urls.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from blog.views import BlogListView, BlogDetailView from django.conf import settings from django.conf.urls import url diff --git a/example/files/admin.py b/example/files/admin.py index 1629d51..6319e3a 100644 --- a/example/files/admin.py +++ b/example/files/admin.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import division, absolute_import, unicode_literals - from django.contrib import admin from .models import CaptionedFile, UncaptionedFile diff --git a/example/files/migrations/0001_initial.py b/example/files/migrations/0001_initial.py index fb58015..7ef76ef 100644 --- a/example/files/migrations/0001_initial.py +++ b/example/files/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/example/files/models.py b/example/files/models.py index 966c611..ea762c3 100644 --- a/example/files/models.py +++ b/example/files/models.py @@ -1,12 +1,7 @@ -# -*- coding: utf-8 -*- -from __future__ import division, absolute_import, unicode_literals - from django.db import models -from django.utils.encoding import python_2_unicode_compatible -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ -@python_2_unicode_compatible class CaptionedFile(models.Model): caption = models.CharField(max_length=200, verbose_name=_('caption')) publication = models.FileField(upload_to='captioned-files', verbose_name=_('Uploaded File')) @@ -19,7 +14,6 @@ class CaptionedFile(models.Model): verbose_name_plural = _('Captioned Files') -@python_2_unicode_compatible class UncaptionedFile(models.Model): publication = models.FileField(upload_to='uncaptioned-files', verbose_name=_('Uploaded File')) diff --git a/example/files/tests/test_views.py b/example/files/tests/test_views.py index 0d743a0..e808e30 100644 --- a/example/files/tests/test_views.py +++ b/example/files/tests/test_views.py @@ -3,7 +3,7 @@ from os import path from django.contrib.auth import get_user_model from django.urls import reverse from django.test import TestCase, Client -from django.utils.encoding import force_text +from django.utils.encoding import force_str from ..models import CaptionedFile @@ -45,7 +45,7 @@ class CaptionedFileListTest(BaseIntegrationTest): def test_actions_displayed(self): response = self.client.get(reverse("admin2:files_captionedfile_index")) self.assertInHTML( - 'Delete selected items', force_text(response.content)) + 'Delete selected items', force_str(response.content)) def test_delete_selected_captioned_file(self): captioned_file = CaptionedFile.objects.create( @@ -55,7 +55,7 @@ class CaptionedFileListTest(BaseIntegrationTest): response = self.client.post( reverse("admin2:files_captionedfile_index"), params) self.assertInHTML( - 'Are you sure you want to delete the selected Captioned File? The following item will be deleted:
', force_text(response.content)) + 'Are you sure you want to delete the selected Captioned File? The following item will be deleted:
', force_str(response.content)) def test_delete_selected_captioned_file_confirmation(self): captioned_file = CaptionedFile.objects.create( @@ -93,7 +93,7 @@ class CaptionedFileCreateViewTest(BaseIntegrationTest): response = self.client.get( reverse("admin2:files_captionedfile_create")) self.assertIn( - 'enctype="multipart/form-data"', force_text(response.content)) + 'enctype="multipart/form-data"', force_str(response.content)) self.assertEqual(response.status_code, 200) def test_create_captioned_file(self): diff --git a/example/polls/admin.py b/example/polls/admin.py index 2a645d5..2969ca4 100644 --- a/example/polls/admin.py +++ b/example/polls/admin.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import division, absolute_import, unicode_literals - from django.contrib import admin from .models import Poll, Choice diff --git a/example/polls/admin2.py b/example/polls/admin2.py index a532b9e..f39ec0f 100644 --- a/example/polls/admin2.py +++ b/example/polls/admin2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import division, absolute_import, unicode_literals - from djadmin2.site import djadmin2_site from djadmin2.types import Admin2TabularInline, ModelAdmin2 from .models import Poll, Choice diff --git a/example/polls/migrations/0001_initial.py b/example/polls/migrations/0001_initial.py index 8dd792e..c4eb624 100644 --- a/example/polls/migrations/0001_initial.py +++ b/example/polls/migrations/0001_initial.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/example/polls/models.py b/example/polls/models.py index a4d14f2..9a6fc52 100644 --- a/example/polls/models.py +++ b/example/polls/models.py @@ -1,15 +1,10 @@ -# -*- coding: utf-8 -*- -from __future__ import division, absolute_import, unicode_literals - import datetime from django.db import models from django.utils import timezone -from django.utils.encoding import python_2_unicode_compatible -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ -@python_2_unicode_compatible class Poll(models.Model): question = models.CharField(max_length=200, verbose_name=_('question')) pub_date = models.DateTimeField(verbose_name=_('date published')) @@ -28,7 +23,6 @@ class Poll(models.Model): verbose_name_plural = _('polls') -@python_2_unicode_compatible class Choice(models.Model): poll = models.ForeignKey( Poll, diff --git a/example/polls/tests/test_views.py b/example/polls/tests/test_views.py index a2bcc65..4f0b37b 100644 --- a/example/polls/tests/test_views.py +++ b/example/polls/tests/test_views.py @@ -2,7 +2,7 @@ from django.contrib.auth import get_user_model from django.test import TestCase, Client from django.urls import reverse from django.utils import timezone -from django.utils.encoding import force_text +from django.utils.encoding import force_str from ..models import Poll @@ -40,7 +40,7 @@ class PollListTest(BaseIntegrationTest): def test_actions_displayed(self): response = self.client.get(reverse("admin2:polls_poll_index")) self.assertInHTML( - 'Delete selected items', force_text(response.content)) + 'Delete selected items', force_str(response.content)) def test_delete_selected_poll(self): poll = Poll.objects.create( @@ -49,7 +49,7 @@ class PollListTest(BaseIntegrationTest): 'selected_model_pk': str(poll.pk)} response = self.client.post(reverse("admin2:polls_poll_index"), params) self.assertInHTML( - 'Are you sure you want to delete the selected poll? The following item will be deleted:
', force_text(response.content)) + 'Are you sure you want to delete the selected poll? The following item will be deleted:
', force_str(response.content)) def test_delete_selected_poll_confirmation(self): poll = Poll.objects.create( diff --git a/fabfile.py b/fabfile.py index f5674ee..af81449 100644 --- a/fabfile.py +++ b/fabfile.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import print_function, division, absolute_import, unicode_literals - from fabric.api import local, lcd from fabric.contrib.console import confirm diff --git a/requirements.txt b/requirements.txt index f16ae34..1c4cc38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ django-extra-views==0.12.0 -django-braces==1.13.0 -djangorestframework==3.9.2 -django-filter==1.1.0 +django-braces==1.14.0 +djangorestframework==3.11.1 +django-filter==2.3.0 django-debug-toolbar>=1.10.1 future>=0.15.2 pytz>=2016.4 diff --git a/setup.py b/setup.py index edface3..7851de5 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from setuptools import setup from setuptools.command.test import test as TestCommand @@ -131,11 +130,11 @@ setup( include_package_data=True, #test_suite='runtests.runtests', install_requires=[ - 'django>=1.11.1', + 'django>=2.2', 'django-extra-views>=0.12.0', 'django-braces>=1.3.0', - 'djangorestframework>=3.9.0', - 'django-filter==1.1.0', + 'djangorestframework>=3.11.1', + 'django-filter==2.3.0', 'pytz>=2016.4', 'future>=0.15.2', ], diff --git a/tox.ini b/tox.ini index 36d60ad..f8c876d 100644 --- a/tox.ini +++ b/tox.ini @@ -6,18 +6,20 @@ exclude = migrations/*,docs/* [tox] envlist = - py27-{1.11}, - py35-{1.11,2.0,2.1}, - py36-{2.0,2.1,master}, + py35-{2.2,3.0}, + py36-{2.2,3.0,3.1}, + py37-{2.2,3.0,3.1,master}, + py38-{2.2,3.0,3.1,master}, + [testenv] commands = py.test [] deps = -rrequirements_test.txt - 2.1: Django>=2.1,<2.2 - 1.11: Django>=1.11,<2.0 - 2.0: Django>=2.0,<2.1 + 3.1: Django>=3.1,<3.2 + 3.0: Django>=3.0,<3.1 + 2.2: Django>=2.2,<2.3 master: https://github.com/django/django/tarball/master setenv= DJANGO_SETTINGS_MODULE = example.settings