From 37304e2b807f1e8d5900a7b7dae6addf717bba40 Mon Sep 17 00:00:00 2001 From: yezyilomo Date: Tue, 31 Dec 2024 10:16:03 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9BMake=20generic=20relation=20support?= =?UTF-8?q?=20optional=20-=20Fixes=20#322?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- django_restql/mixins.py | 46 +++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/django_restql/mixins.py b/django_restql/mixins.py index 85127a6..1e81057 100644 --- a/django_restql/mixins.py +++ b/django_restql/mixins.py @@ -1,10 +1,15 @@ +from django.http import QueryDict from django.db.models import Prefetch +from django.utils.functional import cached_property from django.core.exceptions import ObjectDoesNotExist from django.db.models.fields.related import ManyToManyRel, ManyToOneRel -from django.contrib.contenttypes.fields import GenericRel -from django.contrib.contenttypes.models import ContentType -from django.http import QueryDict -from django.utils.functional import cached_property + +try: + from django.contrib.contenttypes.fields import GenericRel + from django.contrib.contenttypes.models import ContentType +except ImportError: + GenericRel = None + ContentType = None from rest_framework.serializers import ListSerializer, Serializer, ValidationError @@ -637,8 +642,9 @@ def create_many_to_one_generic_related(self, instance, data): field_pks = {} nested_fields = self.restql_writable_nested_fields - content_type = ContentType.objects.get_for_model(instance) - + content_type = ( + ContentType.objects.get_for_model(instance) if ContentType else None + ) for field, values in data.items(): relation = getattr(self.Meta.model, field).field @@ -735,12 +741,12 @@ def create(self, validated_data): if isinstance(rel, ManyToOneRel): value = validated_data_copy.pop(field) fields["many_to"]["one_related"].update({field: value}) - elif isinstance(rel, GenericRel): - value = validated_data_copy.pop(field) - fields["many_to"]["one_generic_related"].update({field: value}) elif isinstance(rel, ManyToManyRel): value = validated_data_copy.pop(field) fields["many_to"]["many_related"].update({field: value}) + elif GenericRel and isinstance(rel, GenericRel): + value = validated_data_copy.pop(field) + fields["many_to"]["one_generic_related"].update({field: value}) foreignkey_related = { **fields["foreignkey_related"]["replaceable"], @@ -755,9 +761,11 @@ def create(self, validated_data): self.create_many_to_one_related(instance, fields["many_to"]["one_related"]) - self.create_many_to_one_generic_related( - instance, fields["many_to"]["one_generic_related"] - ) + if fields["many_to"]["one_generic_related"]: + # Call create_many_to_one_generic_related only if we have generic relationship + self.create_many_to_one_generic_related( + instance, fields["many_to"]["one_generic_related"] + ) return instance @@ -1050,12 +1058,12 @@ def update(self, instance, validated_data): if isinstance(rel, ManyToOneRel): value = validated_data_copy.pop(field) fields["many_to"]["one_related"].update({field: value}) - elif isinstance(rel, GenericRel): - value = validated_data_copy.pop(field) - fields["many_to"]["one_generic_related"][field] = value elif isinstance(rel, ManyToManyRel): value = validated_data_copy.pop(field) fields["many_to"]["many_related"].update({field: value}) + elif GenericRel and isinstance(rel, GenericRel): + value = validated_data_copy.pop(field) + fields["many_to"]["one_generic_related"].update({field: value}) instance = super().update(instance, validated_data_copy) @@ -1071,7 +1079,9 @@ def update(self, instance, validated_data): self.update_many_to_one_related(instance, fields["many_to"]["one_related"]) - self.update_many_to_one_generic_related( - instance, fields["many_to"]["one_generic_related"] - ) + if fields["many_to"]["one_generic_related"]: + # Call update_many_to_one_generic_related only if we have generic relationship + self.update_many_to_one_generic_related( + instance, fields["many_to"]["one_generic_related"] + ) return instance