Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bulk patch fails with unique_together models #57

Open
melinath opened this issue Oct 25, 2016 · 3 comments
Open

Bulk patch fails with unique_together models #57

melinath opened this issue Oct 25, 2016 · 3 comments

Comments

@melinath
Copy link

melinath commented Oct 25, 2016

I ran into an issue with a model I was trying to bulk patch that also has a unique_together constraint. Traceback is below. The issue here is that the UniqueTogetherValidator expects to be called from a serializer with a single related instance (i.e. a normal update serializer). But the serializer is in fact instantiated with a queryset.

TBH I don't entirely understand why serializer.instance is being set to a queryset. But anyway.

Traceback (most recent call last):
  File ".../django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File ".../django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File ".../django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File ".../rest_framework/viewsets.py", line 87, in view
    return self.dispatch(request, *args, **kwargs)
  File ".../rest_framework/views.py", line 466, in dispatch
    response = self.handle_exception(exc)
  File ".../rest_framework/views.py", line 463, in dispatch
    response = handler(request, *args, **kwargs)
  File ".../rest_framework_bulk/drf3/mixins.py", line 79, in partial_bulk_update
    return self.bulk_update(request, *args, **kwargs)
  File ".../rest_framework_bulk/drf3/mixins.py", line 73, in bulk_update
    serializer.is_valid(raise_exception=True)
  File ".../rest_framework/serializers.py", line 213, in is_valid
    self._validated_data = self.run_validation(self.initial_data)
  File ".../rest_framework/serializers.py", line 557, in run_validation
    value = self.to_internal_value(data)
  File ".../rest_framework/serializers.py", line 593, in to_internal_value
    validated = self.child.run_validation(item)
  File ".../rest_framework/serializers.py", line 409, in run_validation
    self.run_validators(value)
  File ".../rest_framework/fields.py", line 498, in run_validators
    validator(value)
  File ".../rest_framework/validators.py", line 142, in __call__
    queryset = self.exclude_current_instance(attrs, queryset)
  File ".../rest_framework/validators.py", line 135, in exclude_current_instance
    return queryset.exclude(pk=self.instance.pk)
AttributeError: 'QuerySet' object has no attribute 'pk'

My workaround was to take advantage of the 'id' attribute that the bulk serializer keeps track of and write a custom unique_together validator.

# validators.py
from rest_framework.validators import UniqueTogetherValidator


class BulkUniqueTogetherValidator(UniqueTogetherValidator):
    def exclude_current_instance(self, attrs, queryset):
        if attrs.get('id'):
            return queryset.exclude(pk=attrs['id'])
        return queryset
# serializers.py
from .validators import BulkUniqueTogetherValidator


class ThingSerializer(serializers.HyperlinkedModelSerializer):
    <...properties>

    def get_unique_together_validators(self):
        return [BulkUniqueTogetherValidator(
            queryset=Thing.objects.all(),
            fields=('field1', 'field2'),
        )]
@msatish9
Copy link

msatish9 commented Dec 5, 2016

Hi @melinath , I see the same issue when trying to implement as in README instructions, could you please elaborate on the workaround? I have a simple model with 2 fields, BulkSerializer and nothing custom. Thanks!

@ibuler
Copy link

ibuler commented Dec 27, 2016

Meet this bug same

@crazy-canux
Copy link

same here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants