beda-software / drf-writable-nested

Writable nested model serializer for Django REST Framework
Other
1.07k stars 115 forks source link

ValueError when trying to set a related id field to the wrong value #152

Open palfrey opened 2 years ago

palfrey commented 2 years ago

Example submission that breaks things (assuming a POST endpoint for a model with a field called foo indexed by ints)

{
  "foo": {
    "id": "5c9db886-ba0e-4fe1-ae61-c26612325a3c"
  }
}

You end up with stacktraces like

File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/mixins.py", line 82, in partial_update
    return self.update(request, *args, **kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/mixins.py", line 68, in update
    self.perform_update(serializer)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/mixins.py", line 78, in perform_update
    serializer.save()
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/drf_writable_nested/mixins.py", line 231, in save
    return super(BaseNestedModelSerializer, self).save(**kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/serializers.py", line 200, in save
    self.instance = self.update(self.instance, validated_data)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/drf_writable_nested/mixins.py", line 288, in update
    self.update_or_create_reverse_relations(instance, reverse_relations)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/drf_writable_nested/mixins.py", line 186, in update_or_create_reverse_relations
    related_instance = serializer.save(**save_kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/drf_writable_nested/mixins.py", line 231, in save
    return super(BaseNestedModelSerializer, self).save(**kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/rest_framework/serializers.py", line 205, in save
    self.instance = self.create(validated_data)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/drf_writable_nested/mixins.py", line 253, in create
    relations,
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/drf_writable_nested/mixins.py", line 212, in update_or_create_direct_relations
    pk=pk,
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/query.py", line 941, in filter
    return self._filter_or_exclude(False, args, kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/query.py", line 961, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, args, kwargs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/query.py", line 968, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1393, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1415, in _add_q
    split_subq=split_subq, check_filterable=check_filterable,
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1347, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1193, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/lookups.py", line 25, in __init__
    self.rhs = self.get_prep_lookup()
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/lookups.py", line 77, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "/Users/tomparker-shemilt/.virtualenvs/case-cards/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 1827, in get_prep_value
    ) from e
ValueError: Field 'id' expected a number but got '5c9db886-ba0e-4fe1-ae61-c26612325a3c'.

I'd expect a serializer error instead!

palfrey commented 2 years ago
{
  "foo": "5c9db886-ba0e-4fe1-ae61-c26612325a3c"
}

gets different, but related tracebacks