Django Rest Framework не может определить имя поля сериализатора
Вот в чем проблема: у меня есть поле сериализатора, указывающее на другой сериализатор. Я посылаю запрос allright на сервер и получаю такой ответ:
{
"purchase_header": [
"This field is required."
]
}
Но поле было отправлено POST-запросом (в отладчике я это вижу).
Я нашел этот код в html.py (из DRF):
def parse_html_dict(dictionary, prefix=''):
"""
Used to support dictionary values in HTML forms.
{
'profile.username': 'example',
'profile.email': 'example@example.com',
}
-->
{
'profile': {
'username': 'example',
'email': 'example@example.com'
}
}
"""
ret = MultiValueDict()
regex = re.compile(r'^%s\.(.+)$' % re.escape(prefix))
for field in dictionary:
match = regex.match(field)
if not match:
continue
key = match.groups()[0]
value = dictionary.getlist(field)
ret.setlist(key, value)
return ret
При отладке я вижу, что переменная prefix содержит "purchase_header", а переменная field содержит ту же строку "purchase_header", но de match fail возвращает None. Очень редко... Параметр dictionary содержит все ключи и значения.
Но если вы можете мне помочь, я буду вам очень признателен.
Это остальная часть значимого кода:
urls.py
router = DefaultRouter()
router.register(r'cancel-requests', PurchaseCancellationsRequestViewSet,
basename='purchase-cancel-requests')
router.register(r'invoices', PurchaseViewSet, basename='purchase')
urlpatterns = router.urls
urlpatterns += [path('payment-headers/', PaymentHeadersListAPIView.as_view(
), name='PaymentHeadersListAPIView')]
api.py
serializers.py
from rest_framework import serializers
from .models import Purchase, PurchaseCancellationRequest, PurchaseHeader
class PurchaseHeaderSerializer(serializers.ModelSerializer):
class Meta:
model = PurchaseHeader
fields = ['id', 'name']
extra = {
'id': {'read_only': True},
'name': {'read_only': True}
}
class PurchaseSerializer(serializers.ModelSerializer):
purchase_header = PurchaseHeaderSerializer()
class Meta:
model = Purchase
fields = ['id', 'cancelled', 'created_at', 'created_by',
'created_for', 'pic', 'total_amount', 'purchase_header']
extra = {
'cancelled': {'read_only': True},
'created_at': {'read_only': True},
'id': {'read_only': True}
}
def validate_total_amount(self, value):
"""
Sanitize the amount value.
:return: total_amount as float
"""
total_amount = None
try:
total_amount = float(value)
except Exception as e:
print(e)
if total_amount:
return value
else:
raise serializers.ValidationError('Exists an error with '
'total_amount value, probably '
'an empty param or bad float '
'format')
def validate_cancelled(self, value):
"""
Sanitize the cancelled value.
:return: cancelled as python boolean
"""
cancelled = None
try:
cancelled = False if value == 'false' else True
except Exception as e:
print(e)
if cancelled:
return value
else:
raise serializers.ValidationError('Exists an error with '
'cancelled value, probably an '
'empty param or bad boolean '
'value')
def create(self, validated_data):
payment_header_pk = validated_data.pop('purchase_header')
payment_header_obj = PaymentHeader.objects.get(pk=payment_header_pk)
purchase_obj = Purchase.objects.create(
payment_header=payment_header_obj, **validated_data)
return purchase_obj
class PurchaseCancellationRequestSerializer(serializers.ModelSerializer):
class Meta:
model = PurchaseCancellationRequest
fields = ['purchase']
models.py
class PurchaseHeader(SoftDeleteModel):
name = models.CharField(max_length=50)
city = models.ManyToManyField(City, through='purchases.ProviderCity')
created_at = models.DateTimeField(default=timezone.now(), editable=False)
modified_at = models.DateTimeField(default=timezone.now())
class ProviderCity(SoftDeleteModel):
city = models.ForeignKey(City, on_delete=models.PROTECT)
purchase_header = models.ForeignKey(PurchaseHeader,
on_delete=models.PROTECT)
class Meta:
unique_together = ('city', 'purchase_header')
Спасибо за всех друзей!!!