Среда REST Django - MultiSelectField - Ошибка типа: объект типа 'set' не поддерживает сериализацию в формате JSON - PullRequest
1 голос
/ 10 мая 2019

Я пытаюсь сделать api с несколькими вариантами выбора с Django REST framework и django-multiselectfield.

В настоящее время внутри модели у меня есть:

ANIMAL = (
    ('dog', 'Dog'),
    ('cat', 'Cat'),
)

class MyForm(models.Model):
    ...
    animals = MultiSelectField(choices=ANIMAL)

и в моем сериализатореУ меня есть:

class MyFormSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyForm
        fields = (..., 'animals')

    animals = fields.MultipleChoiceField(choices=ANIMAL)

Когда я пытаюсь POST в API, используя этот тип тела:

{
    ...
    "animals": ["cat"],
    ...
}

Я получаю ошибку: TypeError: Object of type 'set' is not JSON serializable

Traceback (most recent call last):
  File "C:\Python36\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Python36\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Python36\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Python36\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "c:\mysite\myserver\myform\views.py", line 15, in angels_add
    return JsonResponse(serializer.data, status=201)
  File "C:\Python36\lib\site-packages\django\http\response.py", line 558, in __init__
    data = json.dumps(data, cls=encoder, **json_dumps_params)
  File "C:\Python36\lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "C:\Python36\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Python36\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Python36\lib\site-packages\django\core\serializers\json.py", line 104, in default
    return super().default(o)
  File "C:\Python36\lib\json\encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'set' is not JSON serializable

Хотя форма отправлена, и я вижу все данные в админ-панели успешно (?).

Я использую следующие версии:

  • Django == 2.2.1
  • djangorestframework == 3.9.3
  • django-multiselectfield == 0.1.8

любая идея, почему яполучить это исключение?

также, я могу переключиться с мультиселевого поля на другую технологию, если что-то еще сработает и позволит мне добавить несколько полей выбора, которые я могу отфильтровать позже из панели администратора

class MyFormAdmin(admin.ModelAdmin):
    list_filter = (
        'animals',
        ...
    )

Я читал о ArrayField, но меня не устраивает решение, которое подходит только для одного вида дб (postgres), так как я мог бы использовать другой.

Спасибо заранееe,

Etay.

1 Ответ

3 голосов
/ 10 мая 2019

Из исходного кода метод to_representation() из MultipleChoiceField возвращает данные как set

Создайте собственный класс MultipleChoiceField и используйте его в сериализаторе

class CustomMultipleChoiceField(fields.MultipleChoiceField):
    def to_representation(self, value):
        return list(super().to_representation(value))
class MyFormSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyForm
        fields = (..., 'animals')

    animals = <B>CustomMultipleChoiceField(choices=ANIMAL)</b>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...