diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c595198..6fa5f80 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,14 +15,14 @@ jobs: django-version: [2.2.20, 3.2.12, 4.0.2] drf-version: [3.13.1] include: + - python-version: "3.10" + django-version: 4.1.2 + drf-version: 3.14.0 + variant: default - python-version: "3.10" django-version: 4.0.2 drf-version: 3.13.1 variant: default - - python-version: 3.9 - django-version: 3.2.12 - drf-version: 3.12.4 - variant: default - python-version: 3.9 django-version: 3.2.12 drf-version: 3.13.1 diff --git a/README.md b/README.md index f27663d..ef77ecd 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ [![Python Support](https://img.shields.io/pypi/pyversions/wq.db.svg)](https://pypi.org/project/wq.db) [![Django Support](https://img.shields.io/pypi/djversions/wq.db.svg)](https://pypi.org/project/wq.db) +**Note:** EAV mustache context helpers do not work in Django 4.1 and above. + ### [Documentation][docs] [**Installation**][installation] diff --git a/rest/serializers.py b/rest/serializers.py index 775cd52..b943e3e 100644 --- a/rest/serializers.py +++ b/rest/serializers.py @@ -73,7 +73,6 @@ def to_representation(self, value): MODEL_BOOLEAN_FIELDS = ( model_fields.BooleanField, - model_fields.NullBooleanField, ) @@ -173,13 +172,6 @@ def get_fields_for_config(self): if not has_wq_config: fields.pop(name) - elif isinstance(field, serializers.NullBooleanField): - fields[name] = serializers.ChoiceField( - choices=self.get_boolean_choices(field), - required=False, - label=field.label, - help_text=field.help_text, - ) elif isinstance(field, serializers.BooleanField): fields[name] = serializers.ChoiceField( choices=self.get_boolean_choices(field), diff --git a/setup.py b/setup.py index c30e004..004c51e 100644 --- a/setup.py +++ b/setup.py @@ -65,7 +65,7 @@ def find_wq_packages(submodule): long_description_content_type="text/markdown", install_requires=[ 'Django>=1.11,<5.0', - 'djangorestframework>=3.8.0,<3.14.0', + 'djangorestframework>=3.8.0,<3.15.0', 'html-json-forms', 'natural-keys>=1.6.0', ], @@ -75,9 +75,6 @@ def find_wq_packages(submodule): 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', @@ -90,6 +87,7 @@ def find_wq_packages(submodule): 'Framework :: Django :: 3.1', 'Framework :: Django :: 3.2', 'Framework :: Django :: 4.0', + 'Framework :: Django :: 4.1', 'Topic :: Software Development :: Libraries :: Application Frameworks', 'Topic :: Text Processing :: Markup :: HTML', 'Topic :: Scientific/Engineering :: GIS', diff --git a/tests/rest_app/migrations/0001_initial.py b/tests/rest_app/migrations/0001_initial.py index 174b6aa..c25295f 100644 --- a/tests/rest_app/migrations/0001_initial.py +++ b/tests/rest_app/migrations/0001_initial.py @@ -98,7 +98,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=10)), - ('active', models.NullBooleanField(default=True)), + ('active', models.BooleanField(default=True, null=True)), ], options={ 'abstract': False, diff --git a/tests/rest_app/models.py b/tests/rest_app/models.py index 79420a0..af8fd1e 100644 --- a/tests/rest_app/models.py +++ b/tests/rest_app/models.py @@ -55,7 +55,7 @@ class Child(LabelModel): class ItemType(LabelModel): name = models.CharField(max_length=10) - active = models.NullBooleanField(default=True) + active = models.BooleanField(default=True, null=True) class Item(LabelModel): diff --git a/tests/test_custompatterns.py b/tests/test_custompatterns.py index 67d1041..f0264ce 100644 --- a/tests/test_custompatterns.py +++ b/tests/test_custompatterns.py @@ -1,6 +1,8 @@ +import unittest from wq.db import rest from .base import APITestCase from rest_framework import status +import django from django.contrib.auth.models import User from tests.patterns_app.models import ( CustomPatternModel, CustomTypedPatternModel, CustomType, @@ -13,6 +15,8 @@ EntitySerializerCategoryEmpty, EntitySerializerCategoryCtxt, ) +DJANGO_AFTER_4_0 = (django.VERSION[0] >= 4 and django.VERSION[1] > 0) + class CustomPatternTestCase(APITestCase): def setUp(self): @@ -188,6 +192,7 @@ def test_customtypedpattern_put(self): self.typeinstance.attachments.first().type, self.type ) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_empty(self): rest.router.register_serializer( Entity, @@ -198,6 +203,7 @@ def test_eavfilter_empty(self): [self.att1.id, self.att2.id, self.att3.id, self.att4.id], [i['attribute_id'] for i in response.data['values']]) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_cid(self): rest.router.register_serializer( Entity, @@ -209,6 +215,7 @@ def test_eavfilter_cid(self): [self.att3.id, self.att4.id], [i['attribute_id'] for i in response.data['values']]) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_cid_miss(self): rest.router.register_serializer( Entity, @@ -219,6 +226,7 @@ def test_eavfilter_cid_miss(self): [], [i['attribute_id'] for i in response.data['values']]) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_isactive(self): rest.router.register_serializer( Entity, @@ -238,6 +246,7 @@ def test_eavfilter_isactive(self): [self.att2.id, self.att4.id], [i['attribute_id'] for i in response.data['values']]) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_isactivecid(self): rest.router.register_serializer( Entity, @@ -249,6 +258,7 @@ def test_eavfilter_isactivecid(self): [self.att1.id], [i['attribute_id'] for i in response.data['values']]) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_category(self): rest.router.register_serializer( Entity, @@ -259,6 +269,7 @@ def test_eavfilter_category(self): [self.att1.id, self.att2.id], [i['attribute_id'] for i in response.data['values']]) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_category_empty(self): rest.router.register_serializer( Entity, @@ -269,6 +280,7 @@ def test_eavfilter_category_empty(self): [self.att4.id], [i['attribute_id'] for i in response.data['values']]) + @unittest.skipIf(DJANGO_AFTER_4_0, "EAV mustache context helpers do not work since Django 4.1") def test_eavfilter_category_ctxt_empty(self): rest.router.register_serializer( Entity,