[英]How to serialize three models with many to many relationships in Django Rest Framework
[英]How to serialize creation with Django Rest Framework models with many-to-many field and foreign-key, when models data inside some field in request?
我正在尝试序列化这个 JSON
{
"api_key": "<something key>",
"contract_id": 3808,
"params": {
"contract_id": 3808,
"title": "Глюкоза",
"doctor_description": "Запрашивает у пациента уровень глюкозы в крови.",
"patient_description": "Пожалуйста, измерьте уровень сахара в крови до еды с помощью глюкометра и укажите его в поле ниже.",
"thanks_text": null,
"fields": [
{
"category": "glukose",
"description": "ммоль/л",
"max": null,
"min": null,
"text": "Глюкоза",
"type": "float",
"uid": "24c2258b-d338-4184-a114-5cae3721bb16"
},
{
"category": "information",
"text": "Комментарий",
"type": "textarea",
"uid": "93722301-d652-4903-8404-e56da4d31ad7"
}
]
}
}
在 params 里面有一个模型MeasurementTask
( models.py
) 的实例:
class MeasurementTask(models.Model):
title = models.CharField(max_length=255)
doctor_description = models.TextField()
patient_description = models.TextField()
thanks_text = models.TextField(null=True)
contract_id = models.ForeignKey(Contract, on_delete=models.CASCADE)
fields = models.ManyToManyField(MeasurementTaskGeneric)
is_sent = models.BooleanField(default=False)
is_done = models.BooleanField(default=False)
它由 ManyToManyField 与MeasurementTaskGeneric
相关:
class MeasurementTaskGeneric(models.Model):
uid = models.CharField(max_length=255, unique=True)
category = models.CharField(max_length=255)
description = models.CharField(max_length=255, null=True)
max_value = models.FloatField(null=True)
min_value = models.FloatField(null=True)
text = models.CharField(max_length=255)
value_type = models.CharField(max_length=255)
并使用带有Contract
外键:
class Contract(models.Model):
contract_id = models.IntegerField(unique=True, primary_key=True)
speaker_active = models.BooleanField(default=False)
def __str__(self):
return "Contract id - {}".format(self.contract_id)
随着请求,我需要创建MeasurementTask
实例并创建(或获取,如果它已经存在)的MeasurementTaskGeneric
实例,通过Contract.contract_id
获取Contract
的实例并将其添加到MeasurementTask.contract_id
我正在使用这个序列化器来序列化它( serializers.py
):
from rest_framework import serializers
from medsenger_agent.models import MeasurementTask, MeasurementTaskGeneric
class TaskGenericSerializer(serializers.ModelSerializer):
class Meta:
model = MeasurementTaskGeneric
fields = '__all__'
def get_fields(self):
result = super().get_fields()
type_ = result.pop('value_type')
result['type'] = type_
return result
class TaskModelSerializer(serializers.ModelSerializer):
contract_id = serializers.ReadOnlyField(
source='contract.contract_id', )
fields = serializers.ListField(
child=TaskGenericSerializer())
class Meta:
model = MeasurementTask
fields = '__all__'
class TaskSerializer(serializers.Serializer):
api_key = serializers.CharField()
contract_id = serializers.IntegerField()
params = TaskModelSerializer()
和views.py
:
from rest_framework.generics import CreateAPIView
from medsenger_agent import serializers
class OrderApiView(CreateAPIView):
serializer_class = serializers.TaskSerializer
最后我收到了这个错误
Traceback (most recent call last):
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/asgiref/sync.py", line 482, in thread_handler
raise exc_info[1]
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/django/core/handlers/exception.py", line 38, in inner
response = await get_response(request)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/django/core/handlers/base.py", line 233, in _get_response_async
response = await wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/asgiref/sync.py", line 444, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/asyncio/tasks.py", line 455, in wait_for
return await fut
File "/Users/tikhon/opt/anaconda3/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/asgiref/sync.py", line 486, in thread_handler
return func(*args, **kwargs)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/generics.py", line 190, in post
return self.create(request, *args, **kwargs)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/mixins.py", line 19, in create
self.perform_create(serializer)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/mixins.py", line 24, in perform_create
serializer.save()
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/serializers.py", line 205, in save
self.instance = self.create(validated_data)
File "/Users/tikhon/opt/anaconda3/lib/python3.8/site-packages/rest_framework/serializers.py", line 170, in create
raise NotImplementedError('`create()` must be implemented.')
NotImplementedError: `create()` must be implemented.
我知道我需要提供.create()
方法来创建序列化程序,但我不知道如何...
由于低代表,我无法发表评论,但这是来自classyDRF的功能
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
所以对你来说,这可能意味着:
from rest_framework.generics import CreateAPIView
from medsenger_agent import serializers
class OrderApiView(CreateAPIView):
serializer_class = serializers.TaskSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
编辑:classyDRF 不是官方文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.