Skip to content

Commit 7683289

Browse files
authored
chore: Compatibility with django 5.x (#8)
1 parent dcc6213 commit 7683289

File tree

8 files changed

+140
-56
lines changed

8 files changed

+140
-56
lines changed

.github/workflows/test.yml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@ jobs:
77
runs-on: ubuntu-latest
88
strategy:
99
matrix:
10-
python-version: ["3.8", "3.9"]
11-
django-version: ["2.2", "3.2", "4.2"]
1210
include:
13-
- python-version: "3.7"
14-
django-version: "2.2"
15-
- python-version: "3.10"
16-
django-version: "3.2"
17-
- python-version: "3.10"
18-
django-version: "4.2"
19-
- python-version: "3.11"
20-
django-version: "4.2"
11+
- django-version: "2.2"
12+
python-version: "3.8"
13+
- django-version: "3.2"
14+
python-version: "3.9"
15+
- django-version: "4.2"
16+
python-version: "3.10"
17+
- django-version: "4.2"
18+
python-version: "3.11"
19+
- django-version: "5.1"
20+
python-version: "3.12"
21+
- django-version: "5.2"
22+
python-version: "3.13"
2123

2224
name: Django ${{ matrix.django-version }} (Python ${{ matrix.python-version }})
2325

generic_plus/curation/fields.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ def __init__(self, ct_field='content_type', fk_field='object_id',
5656

5757
@property
5858
def attname(self):
59-
return self.name
59+
if not hasattr(self, "_attname"):
60+
self._attname = self.name
61+
return self._attname
62+
63+
@attname.setter
64+
def attname(self, value):
65+
self._attname = value
6066

6167
def formfield(self, **kwargs):
6268
defaults = {

generic_plus/fields.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class GenericForeignFileField(GenericRelation):
6666
generic_descriptor = None
6767
file_descriptor = None
6868

69+
empty_strings_allowed = True
70+
rel_class = GenericRel
71+
6972
file_descriptor_cls = FileDescriptor
7073
file_field_cls = models.FileField
7174
rel_file_field_name = 'file'
@@ -134,6 +137,9 @@ def __init__(self, to, rel_file_field_name=None, field_identifier="",
134137

135138
self.file_kwargs['db_column'] = kwargs.get('db_column', self.name)
136139

140+
def get_cache_name(self):
141+
return self.name
142+
137143
def get_cached_value(self, instance, **kwargs):
138144
cache_name = self.get_cache_name()
139145
if django.VERSION > (2, 0):
@@ -219,6 +225,16 @@ def is_cached(self, instance):
219225
return hasattr(instance, self.get_cache_name())
220226

221227
def get_prefetch_queryset(self, instances, queryset=None):
228+
if queryset is None:
229+
return self.get_prefetch_querysets(instances)
230+
return self.get_prefetch_querysets(instances, [queryset])
231+
232+
def get_prefetch_querysets(self, instances, querysets=None):
233+
if querysets is not None:
234+
raise Exception(
235+
"Passing querysets in generic_plus get_prefetch_querysets is "
236+
"not yet supported"
237+
)
222238
models = set([type(i) for i in instances])
223239

224240
# Handle case where instances are different models (and consequently,
@@ -401,7 +417,15 @@ def __get__(self, instance, instance_type=None):
401417
'prefetch_cache_name': self.field.attname,
402418
}
403419

404-
join_cols = self.field.get_joining_columns(reverse_join=True)[0]
420+
if hasattr(self.field, "get_joining_fields"):
421+
join_cols = tuple(
422+
(lhs_field.column, rhs_field.column)
423+
for lhs_field, rhs_field in self.field.get_joining_fields(
424+
reverse_join=True
425+
)
426+
)[0]
427+
else:
428+
join_cols = self.field.get_joining_columns(reverse_join=True)[0]
405429

406430
ct_manager = ContentType.objects.db_manager(instance._state.db)
407431
content_type = ct_manager.get_for_model(instance, for_concrete_model=self.for_concrete_model)

generic_plus/tests/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import warnings
2+
3+
import pytest
4+
from django.test import TestCase
5+
6+
7+
TestCase.pytestmark = pytest.mark.django_db(transaction=True, reset_sequences=True)
8+
9+
10+
@pytest.fixture(autouse=True)
11+
def suppress_warnings():
12+
warnings.simplefilter("error", Warning)

pyproject.toml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
[build-system]
2+
build-backend = "setuptools.build_meta"
3+
requires = ["setuptools>=75.3.2"]
4+
5+
[project]
6+
name = "django-generic-plus"
7+
dynamic = ["version"]
8+
description = "Django model field that combines the functionality of GenericForeignKey and FileField"
9+
readme = "README.rst"
10+
license = { text = "BSD-2-Clause" }
11+
requires-python = ">=3"
12+
authors = [
13+
{ name = "The Atlantic", email = "[email protected]" },
14+
]
15+
classifiers = [
16+
"Development Status :: 5 - Production/Stable",
17+
"Environment :: Web Environment",
18+
"Framework :: Django",
19+
"Framework :: Django :: 2.2",
20+
"Framework :: Django :: 3.2",
21+
"Framework :: Django :: 4.2",
22+
"Framework :: Django :: 5.0",
23+
"Framework :: Django :: 5.1",
24+
"Framework :: Django :: 5.2",
25+
"Programming Language :: Python :: 3 :: Only",
26+
"Programming Language :: Python :: 3.7",
27+
"Programming Language :: Python :: 3.8",
28+
"Programming Language :: Python :: 3.9",
29+
"Programming Language :: Python :: 3.10",
30+
"Programming Language :: Python :: 3.11",
31+
"Programming Language :: Python :: 3.12",
32+
"Programming Language :: Python :: 3.13",
33+
]
34+
dependencies = [
35+
"python-monkey-business>=1.0.0",
36+
]
37+
38+
[project.urls]
39+
Homepage = "https://github.com/theatlantic/django-generic-plus"
40+
41+
[tool.setuptools]
42+
zip-safe = false
43+
platforms = ["any"]
44+
include-package-data = true
45+
46+
[tool.setuptools.packages.find]
47+
include = ["generic_plus*"]
48+
namespaces = false
49+
50+
[tool.setuptools.dynamic]
51+
version = { attr = "generic_plus.__version__" }
52+
readme = { file = ["README.rst"] }

pytest.ini

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[pytest]
2+
DJANGO_SETTINGS_MODULE = generic_plus.tests.settings
3+
addopts = --tb=short --create-db
4+
django_find_project = false
5+
python_files = tests.py test_*.py *_tests.py
6+
pythonpath = .
7+
testpaths = generic_plus/tests

setup.py

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,3 @@
1-
#!/usr/bin/env python
2-
from setuptools import setup, find_packages
1+
from setuptools import setup
32

4-
5-
setup(
6-
name='django-generic-plus',
7-
version=__import__("generic_plus").__version__,
8-
install_requires=[
9-
'python-monkey-business>=1.0.0',
10-
],
11-
description="Django model field that combines the functionality of "
12-
"GenericForeignKey and FileField",
13-
long_description=open('README.rst').read(),
14-
license='BSD',
15-
platforms="any",
16-
author='The Atlantic',
17-
author_email='[email protected]',
18-
url='https://github.com/theatlantic/django-generic-plus',
19-
packages=find_packages(),
20-
python_requires='>=3',
21-
classifiers=[
22-
'Development Status :: 5 - Production/Stable',
23-
'Environment :: Web Environment',
24-
'Intended Audience :: Developers',
25-
'Natural Language :: English',
26-
'Operating System :: OS Independent',
27-
'Framework :: Django',
28-
'Framework :: Django :: 3.2',
29-
'Framework :: Django :: 4.0',
30-
'Framework :: Django :: 4.1',
31-
'Programming Language :: Python',
32-
'Programming Language :: Python :: 3',
33-
'Programming Language :: Python :: 3 :: Only',
34-
'Programming Language :: Python :: 3.7',
35-
'Programming Language :: Python :: 3.8',
36-
'Programming Language :: Python :: 3.9',
37-
'Programming Language :: Python :: 3.10',
38-
],
39-
include_package_data=True,
40-
zip_safe=False)
3+
setup()

tox.ini

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
[tox]
22
envlist =
3-
py{37,38,39}-dj22
4-
py{37,38,39,310}-dj32
5-
py{38,39,310,311}-dj42
3+
py{36,37,38,39}-dj22
4+
py{36,37,38,39,310}-dj32
5+
py{38,39,310}-dj40
6+
py{38,39,310,311}-dj41
7+
py{38,39,310,311,312}-dj42
8+
py{310,311,312}-dj{50,51}
9+
py{310,311,312,313}-dj52
610

711
[gh-actions]
812
python =
@@ -11,16 +15,23 @@ python =
1115
3.9: py39
1216
3.10: py310
1317
3.11: py311
18+
3.12: py312
19+
3.13: py313
1420

1521
[gh-actions:env]
1622
DJANGO =
1723
2.2: dj22
1824
3.2: dj32
25+
4.0: dj40
26+
4.1: dj41
1927
4.2: dj42
28+
5.0: dj50
29+
5.1: dj51
30+
5.2: dj52
2031

2132
[testenv]
2233
commands =
23-
python runtests.py {posargs} --noinput
34+
pytest {posargs}
2435
passenv =
2536
DATABASE_URL
2637
deps =
@@ -29,4 +40,11 @@ deps =
2940
!dj22: dj-database-url
3041
dj22: Django>=2.2,<3.0
3142
dj32: Django>=3.2,<4.0
32-
dj42: Django>=4.2,<5.0
43+
dj40: Django>=4.0,<4.1
44+
dj41: Django>=4.1,<4.2
45+
dj42: Django>=4.2,<4.3
46+
dj50: Django>=5.0,<5.1
47+
dj51: Django>=5.1a1,<5.2
48+
dj52: Django>=5.2,<5.3
49+
pytest
50+
pytest-django

0 commit comments

Comments
 (0)