Django REST Framework UniqueTogetherValidator - PullRequest
0 голосов
/ 07 июня 2019

Описание проблемы:

DRF UniqueTogetherValidator отображает странное поведение.Например:

models.py

class MyModel1(models.Model):
    field1 = models.IntegerField()
    field2 = models.ForeignKey('MyModel2', on_delete...)

class MyModel2(models.Model):
    field3 = models.IntegerField()

serializer.py

from rest_framework.validators import UniqueTogetherValidator

class MyModel1Seriealizer(serializers.ModelSerializer):
    class Meta:
        model = MyModel1
        validators = [
            UniqueTogetherValidator(
                queryset=MyModel1.objects.all(),
                fields=('field1', 'field2_id')
            )
        ]

При нарушении условиятолько field1 возвращает 400 хороших ответов с сообщением в non_field_errors, но когда нарушенное поле равно field2 (или _id), сервер возвращает код ответа 500 (что означает, что Django перехватилэто на уровне базы данных / ORM).

Фактический вариант использования здесь, на моем GitHub .

Полный возврат

Internal Server Error: /parts/10/
Traceback (most recent call last):
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: part_management_part.class_code_id, part_management_part.number

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 116, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 84, in partial_update
    return self.update(request, *args, **kwargs)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 70, in update
    self.perform_update(serializer)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/mixins.py", line 80, in perform_update
    serializer.save()
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 209, in save
    self.instance = self.update(self.instance, validated_data)
  File "/home/anani/PycharmProjects/part_management_backend/part_management/serializers.py", line 55, in update
    instance.save()
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 741, in save
    force_update=force_update, update_fields=update_fields)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 779, in save_base
    force_update, using, update_fields,
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 851, in _save_table
    forced_update)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/base.py", line 900, in _do_update
    return filtered._update(values) > 0
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/query.py", line 760, in _update
    return query.get_compiler(self.db).execute_sql(CURSOR)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1429, in execute_sql
    cursor = super().execute_sql(result_type)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1100, in execute_sql
    cursor.execute(sql, params)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 99, in execute
    return super().execute(sql, params)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/anani/PycharmProjects/part_management_backend/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: part_management_part.class_code_id, part_management_part.number
[06/Jun/2019 23:37:04] "PATCH /parts/10/ HTTP/1.1" 500 22340

1 Ответ

0 голосов
/ 07 июня 2019

если field2_id - внешний ключ, вам не нужно ставить поле таким образом.просто введите field2

from rest_framework.validators import UniqueTogetherValidator

class MyModel1Seriealizer(serializers.ModelSerializer):
    class Meta:
        model = MyModel1
        validators = [
            UniqueTogetherValidator(
                queryset=MyModel1.objects.all(),
                fields=('field1', 'field2')
            )
        ]

, и вы можете попробовать опубликовать данные json следующим образом:

{
  "field2": 1,
  "field1": "test",
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...