Предоставление MoneyFields в Django REST Framework? - PullRequest
0 голосов
/ 13 марта 2020

У меня есть Django модели, которые используют djmoney.models.fields.MoneyField. Это хранит данные, такие как «US $ 1,000.00».

Я пытаюсь представить это через API с Django REST Framework непосредственно в администраторе Django с пользовательским представлением, например :

from rest_framework import generics
from rest_framework import serializers

class MyModelAdmin(admin.ModelAdmin):

    def changelist_view_api(self, request, extra_context=None):

        cl = self.get_changelist_instance(request)
        base_queryset = cl.get_queryset(request)

        fieldsets = self.get_fieldsets(request)

        class ModelSerializer(serializers.ModelSerializer):

            class Meta:
                model = self.model
                fields = all_fields

        class ModelAdminListAPI(generics.ListCreateAPIView):
            queryset = base_queryset
            serializer_class = ModelSerializer

            name = '%s List API' % self.model._meta.verbose_name.title()

            def get(self, request, *args, **kwargs):
                return self.list(request, *args, **kwargs)

        view_handler = ModelAdminListAPI.as_view(queryset=base_queryset, serializer_class=ModelSerializer)
        return view_handler(request, extra_context, format=_format)

Это работает хорошо, за исключением того, что он задыхается в этих специальных экземплярах MoneyField. С одним из них в списке полей это представление возвращает исключение:

  File "~/.env/lib/python3.7/site-packages/rest_framework/mixins.py", line 43, in list
    return self.get_paginated_response(serializer.data)
  File "~/.env/lib/python3.7/site-packages/rest_framework/serializers.py", line 761, in data
    ret = super().data
  File "~/.env/lib/python3.7/site-packages/rest_framework/serializers.py", line 260, in data
    self._data = self.to_representation(self.instance)
  File "~/.env/lib/python3.7/site-packages/rest_framework/serializers.py", line 679, in to_representation
    self.child.to_representation(item) for item in iterable
  File "~/.env/lib/python3.7/site-packages/rest_framework/serializers.py", line 679, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "~/.env/lib/python3.7/site-packages/rest_framework/serializers.py", line 530, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "~/.env/lib/python3.7/site-packages/rest_framework/fields.py", line 1148, in to_representation
    value = decimal.Decimal(str(value).strip())
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]

При копании во внутренностях DRF, кажется, что он обрабатывает MoneyField как DecimalField, так как это то, от чего он наследуется. Тем не менее, djmoney также создает другое CharField с именем *_currency, в котором хранится номинал валюты (например, «USD»). Затем, когда вы запрашиваете логическое значение для денежного поля, оно объединяет десятичное и валютное значения в формат "".

Я думаю, что DRF сталкивается с проблемой, когда он пытается интерпретировать это значение как десятичное .

Это ошибка в DRF или неправильно настроена? Как мне разрешить DRF правильно интерпретировать значения MoneyField?

...