Skip to content

Commit

Permalink
Add support for django 4.0, drop support for python 3.5 (#822)
Browse files Browse the repository at this point in the history
  • Loading branch information
jieter authored Oct 5, 2021
1 parent 51a1101 commit bde371f
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 100 deletions.
14 changes: 8 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
django-version: [2.2, 3.1, 3.2]
python-version: [3.6, 3.7, 3.8, 3.9]
django-version: [2.2, 3.1, 3.2, 4.0a1]
exclude:
- python-version: 3.5
django-version: 3.1
- python-version: 3.5
django-version: 3.2
- python-version: 3.6
django-version: 4.0a1
- python-version: 3.7
django-version: 4.0a1
- python-version: 3.8
django-version: 2.2
- python-version: 3.9
django-version: 2.2
- python-version: "3.10"
django-version: 2.2


steps:
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/ambv/black
rev: stable
rev: 21.9b0
hooks:
- id: black
language_version: python3.7
2 changes: 1 addition & 1 deletion requirements/common.pip
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ tablib[xls,yaml]
# https://bitbucket.org/openpyxl/openpyxl/issues/1373/broken-writer-with-lxml-defusedxml
openpyxl==2.6.4
mock==3.0.5
psycopg2-binary==2.8.5
psycopg2-binary==2.9.1
django-filter==2.3.0
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"Framework :: Django :: 2.2",
"Framework :: Django :: 3.1",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.0",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
Expand All @@ -39,6 +40,7 @@
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Software Development :: Libraries",
],
Expand Down
90 changes: 50 additions & 40 deletions tests/app/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.0 on 2019-09-23 17:47
# Generated by Django 4.0a1 on 2021-09-22 18:51

from django.db import migrations, models
import django.db.models.deletion
Expand All @@ -8,35 +8,25 @@ class Migration(migrations.Migration):

initial = True

dependencies = [("contenttypes", "0002_remove_content_type_name")]
dependencies = [
("contenttypes", "0002_remove_content_type_name"),
]

operations = [
migrations.CreateModel(
name="Group",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("name", models.CharField(max_length=200)),
],
),
migrations.CreateModel(
name="Occupation",
fields=[
(
"id",
models.AutoField(
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("name", models.CharField(max_length=200)),
("boolean", models.NullBooleanField()),
("boolean", models.BooleanField(null=True)),
(
"boolean_with_choices",
models.NullBooleanField(choices=[(True, "Yes"), (False, "No")]),
models.BooleanField(choices=[(True, "Yes"), (False, "No")], null=True),
),
],
),
Expand All @@ -45,7 +35,7 @@ class Migration(migrations.Migration):
fields=[
(
"id",
models.AutoField(
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
Expand All @@ -71,7 +61,7 @@ class Migration(migrations.Migration):
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="contenttypes.ContentType",
to="contenttypes.contenttype",
),
),
("friends", models.ManyToManyField(to="app.Person")),
Expand All @@ -81,66 +71,86 @@ class Migration(migrations.Migration):
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="people",
to="app.Occupation",
to="app.occupation",
verbose_name="occupation of the person",
),
),
],
options={"verbose_name": "person", "verbose_name_plural": "people"},
options={
"verbose_name": "person",
"verbose_name_plural": "people",
},
),
migrations.CreateModel(
name="PersonInformation",
name="Region",
fields=[
(
"id",
models.AutoField(
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("name", models.CharField(max_length=200)),
(
"person",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="info_list",
to="app.Person",
verbose_name="Information",
"mayor",
models.OneToOneField(
null=True, on_delete=django.db.models.deletion.CASCADE, to="app.person"
),
),
],
options={
"ordering": ["name"],
},
),
migrations.CreateModel(
name="Region",
name="PersonInformation",
fields=[
(
"id",
models.AutoField(
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("name", models.CharField(max_length=200)),
(
"mayor",
models.OneToOneField(
null=True, on_delete=django.db.models.deletion.CASCADE, to="app.Person"
"person",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="info_list",
to="app.person",
verbose_name="Information",
),
),
],
options={"ordering": ["name"]},
),
migrations.AddField(
model_name="occupation",
name="region",
field=models.ForeignKey(
null=True, on_delete=django.db.models.deletion.CASCADE, to="app.Region"
null=True, on_delete=django.db.models.deletion.CASCADE, to="app.region"
),
),
migrations.AddField(
model_name="group", name="members", field=models.ManyToManyField(to="app.Person")
migrations.CreateModel(
name="Group",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("name", models.CharField(max_length=200)),
("members", models.ManyToManyField(to="app.Person")),
],
),
migrations.CreateModel(
name="PersonProxy",
fields=[],
options={"ordering": ("last_name",), "proxy": True, "indexes": []},
options={
"ordering": ("last_name",),
"proxy": True,
"indexes": [],
"constraints": [],
},
bases=("app.person",),
),
]
19 changes: 0 additions & 19 deletions tests/app/migrations/0002_auto_20200812_0958.py

This file was deleted.

4 changes: 0 additions & 4 deletions tests/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,4 @@

TIME_ZONE = "Europe/Amsterdam"

SHORT_DATE_FORMAT = "Y-m-d"
TIME_FORMAT = "H:i:s"
SHORT_DATETIME_FORMAT = "Y-m-d H:i:s"

USE_TZ = True
17 changes: 7 additions & 10 deletions tests/columns/test_datecolumn.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import date

from django.db import models
from django.test import SimpleTestCase, override_settings
from django.test import SimpleTestCase

import django_tables2 as tables

Expand Down Expand Up @@ -35,7 +35,6 @@ class Meta:
)
self.assertEqual(table.rows[1].get_cell("date"), "—")

@override_settings(DATE_FORMAT="D Y b")
def test_should_handle_long_format(self):
class TestTable(tables.Table):
date = tables.DateColumn(short=False)
Expand All @@ -44,10 +43,9 @@ class Meta:
default = "—"

table = TestTable([{"date": date(2012, 9, 11)}, {"date": None}])
assert table.rows[0].get_cell("date") == "Tue 2012 sep"
assert table.rows[1].get_cell("date") == "—"
self.assertEqual(table.rows[0].get_cell("date"), "Sept. 11, 2012")
self.assertEqual(table.rows[1].get_cell("date"), "—")

@override_settings(SHORT_DATE_FORMAT="b Y D")
def test_should_handle_short_format(self):
class TestTable(tables.Table):
date = tables.DateColumn(short=True)
Expand All @@ -56,8 +54,8 @@ class Meta:
default = "—"

table = TestTable([{"date": date(2012, 9, 11)}, {"date": None}])
assert table.rows[0].get_cell("date") == "sep 2012 Tue"
assert table.rows[1].get_cell("date") == "—"
self.assertEqual(table.rows[0].get_cell("date"), "09/11/2012")
self.assertEqual(table.rows[1].get_cell("date"), "—")

def test_should_be_used_for_datefields(self):
class DateModel(models.Model):
Expand All @@ -72,14 +70,13 @@ class Meta:

self.assertEqual(type(Table.base_columns["field"]), tables.DateColumn)

@override_settings(SHORT_DATE_FORMAT="b Y D")
def test_value_returns_a_raw_value_without_html(self):
class Table(tables.Table):
date = tables.DateColumn()
date_linkify = tables.DateColumn(accessor="date", linkify=isoformat_link)

table = Table([{"date": date(2012, 9, 12)}])
self.assertEqual(table.rows[0].get_cell_value("date"), "sep 2012 Wed")
self.assertEqual(table.rows[0].get_cell_value("date"), "09/12/2012")
self.assertEqual(
table.rows[0].get_cell("date_linkify"), '<a href="/test/2012-09-12/">sep 2012 Wed</a>'
table.rows[0].get_cell("date_linkify"), '<a href="/test/2012-09-12/">09/12/2012</a>'
)
11 changes: 4 additions & 7 deletions tests/columns/test_datetimecolumn.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytz
from django.conf import settings
from django.db import models
from django.test import SimpleTestCase, override_settings
from django.test import SimpleTestCase

import django_tables2 as tables

Expand Down Expand Up @@ -44,7 +44,6 @@ class Meta:
)
self.assertEqual(table.rows[1].get_cell("date"), "—")

@override_settings(DATETIME_FORMAT="D Y b A f")
def test_should_handle_long_format(self):
class TestTable(tables.Table):
date = tables.DateTimeColumn(short=False)
Expand All @@ -53,10 +52,9 @@ class Meta:
default = "—"

table = TestTable([{"date": self.dt()}, {"date": None}])
self.assertEqual(table.rows[0].get_cell("date"), "Tue 2012 sep PM 12:30")
self.assertEqual(table.rows[0].get_cell("date"), "Sept. 11, 2012, 12:30 p.m.")
self.assertEqual(table.rows[1].get_cell("date"), "—")

@override_settings(SHORT_DATETIME_FORMAT="b Y D A f")
def test_should_handle_short_format(self):
class TestTable(tables.Table):
date = tables.DateTimeColumn(short=True)
Expand All @@ -65,7 +63,7 @@ class Meta:
default = "—"

table = TestTable([{"date": self.dt()}, {"date": None}])
self.assertEqual(table.rows[0].get_cell("date"), "sep 2012 Tue PM 12:30")
self.assertEqual(table.rows[0].get_cell("date"), "09/11/2012 12:30 p.m.")
self.assertEqual(table.rows[1].get_cell("date"), "—")

def test_should_be_used_for_datetimefields(self):
Expand All @@ -81,10 +79,9 @@ class Meta:

self.assertIsInstance(Table.base_columns["field"], tables.DateTimeColumn)

@override_settings(SHORT_DATETIME_FORMAT="b Y D A f")
def test_value_returns_a_raw_value_without_html(self):
class Table(tables.Table):
col = tables.DateTimeColumn()

table = Table([{"col": self.dt()}])
self.assertEqual(table.rows[0].get_cell_value("col"), "sep 2012 Tue PM 12:30")
self.assertEqual(table.rows[0].get_cell_value("col"), "09/11/2012 12:30 p.m.")
6 changes: 2 additions & 4 deletions tests/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,11 @@ def get_queryset(self):
response = View.as_view()(build_request("/?_export=csv"))
data = response.getvalue().decode("utf8")

expected_csv = "\r\n".join(
("Date,Time,Datetime", "2019-07-22,11:11:11,2019-07-22 13:11:11", "")
)
expected_csv = "Date,Time,Datetime\r\n07/22/2019,11:11 a.m.,07/22/2019 1:11 p.m.\r\n"
self.assertEqual(data, expected_csv)

response = View.as_view()(build_request("/?_export=xls"))
self.assertIn("2019-07-22 13:11:11".encode(), response.content)
self.assertIn("07/22/2019 1:11 p.m.".encode(), response.content)

def test_export_invisible_columns(self):
"""Verify columns with visible=False *do* get exported."""
Expand Down
Loading

0 comments on commit bde371f

Please sign in to comment.