diff --git a/binder/views.py b/binder/views.py index b8166326..332b4829 100644 --- a/binder/views.py +++ b/binder/views.py @@ -2325,8 +2325,17 @@ def _multi_put_override_superclass(self, objects): # Collect overrides for (cls, mid), data in objects.items(): for subcls in getsubclasses(cls): + # Get remote field of the subclass + remote_field = subcls._meta.pk.remote_field + + # In some scenarios with proxy models + # The remote field may not exist + # Because proxy models are just pure python wrappers(without its own db table) for other models + if remote_field is None: + continue + # Get key of field pointing to subclass - subkey = subcls._meta.pk.remote_field.name + subkey = remote_field.name # Get id of subclass subid = data.pop(subkey, None) if subid is None: diff --git a/docker-compose.yml b/docker-compose.yml index 5e890a8a..b0aeb0c7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3' - services: db: image: postgres:11.5 diff --git a/setup.py b/setup.py index b2174ccc..a7f8936b 100755 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', ], install_requires=[ - 'Django >= 3.0, < 5.0', + 'Django >= 3.0, < 4.0', 'Pillow >= 3.2.0', 'django-request-id >= 1.0.0', 'requests >= 2.13.0', diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py index 6cc8cf15..7deb1cd2 100644 --- a/tests/test_inheritance.py +++ b/tests/test_inheritance.py @@ -122,3 +122,24 @@ def test_create_lion_with_animal_and_zoo(self): zoo = Zoo.objects.get(pk=zoo_id) zoo_animal_ids = [animal.id for animal in zoo.animals.all()] self.assertEqual(zoo_animal_ids, [animal_id]) + + def test_multiput_class_that_has_proxy_subclass(self): + response = self.client.put( + '/animal/', + content_type='application/json', + data=json.dumps({ + 'data': [{ + 'id': -1, + 'name': 'Kowalsky', + }], + 'with': { + 'zoo': [{ + 'id': -3, + 'name': 'Artis', + 'animals': [-1], + }], + }, + }), + ) + + self.assertEqual(response.status_code, 200) diff --git a/tests/testapp/models/__init__.py b/tests/testapp/models/__init__.py index 93af8bc6..f03ff3bb 100644 --- a/tests/testapp/models/__init__.py +++ b/tests/testapp/models/__init__.py @@ -16,6 +16,7 @@ from .city import City, CityState, PermanentCity from .country import Country from .web_page import WebPage +from .pet import Pet # This is Postgres-specific if os.environ.get('BINDER_TEST_MYSQL', '0') != '1': diff --git a/tests/testapp/models/pet.py b/tests/testapp/models/pet.py new file mode 100644 index 00000000..48b3b0bf --- /dev/null +++ b/tests/testapp/models/pet.py @@ -0,0 +1,7 @@ +from binder.models import BinderModel + +from .animal import Animal + +class Pet(Animal): + class Meta(BinderModel.Meta): + proxy = True diff --git a/tests/testapp/views/__init__.py b/tests/testapp/views/__init__.py index 000623a2..31fb1049 100644 --- a/tests/testapp/views/__init__.py +++ b/tests/testapp/views/__init__.py @@ -21,3 +21,4 @@ from .zoo_employee import ZooEmployeeView from .web_page import WebPageView from .donor import DonorView +from .pet import PetView diff --git a/tests/testapp/views/pet.py b/tests/testapp/views/pet.py new file mode 100644 index 00000000..d55ac301 --- /dev/null +++ b/tests/testapp/views/pet.py @@ -0,0 +1,6 @@ +from binder.views import ModelView + +from ..models import Pet + +class PetView(ModelView): + model = Pet