我正在从事一个NextJS + Django REST框架项目,其中有三个模型: Document、MySource和QuestionBlock。
POST请求:注意我如何将文档的id放在我想要链接的.中
{
"url": "urlasdf",
"title": "tuitle",
"publisher": "afdfas ",
"desc": "qwefqwef",
"summary": "asdfasdf",
"document": "J9DY2pE"
}
GET请求:我希望文档GET请求显示如下所示。
"id": "LwpQr6Y",
"question_blocks": [
{
"id": 16,
"document": "LwpQr6Y",
"title": "question 4",
"content": "qweqgadssdffasdf asdf"
},
]
"mysource": [
{
"id": 16,
"url": "google.com",
etc. . .
},
],
"title": "renamed title",
"template": "commonapp",
"updated": "2022-05-19T02:16:00+0000",
"created": "2022-04-21T06:59:05+0000"
奇怪的是,我没有看到下面的代码有任何错误,而且功能本身也正常工作。但是,当我试图获得至少有一个mysource对象的文档时,加载它需要几分钟时间,这让我认为我的代码有问题,可能会让DRF自己重复。
models.py
class Document(models.Model):
id = HashidAutoField(primary_key=True)
title = models.CharField(max_length=100, default="Untitled")
template = models.CharField(max_length=100, default="")
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class QuestionBlock(models.Model):
id = models.AutoField(primary_key=True)
document = models.ForeignKey(
Document,
related_name="question_blocks",
on_delete=models.CASCADE,
null=True,
blank=True,
)
title = models.CharField(max_length=500, default="")
content = models.CharField(max_length=100000, default="", blank=True)
class MySource(models.Model):
id = models.AutoField(primary_key=True)
document = models.ForeignKey(
Document,
related_name="mysource",
on_delete=models.CASCADE,
null=True,
blank=True,
)
url = models.CharField(max_length=500, default="")
title = models.CharField(max_length=500, default="", blank=True)
publisher = models.CharField(max_length=500, default="", blank=True)
desc = models.CharField(max_length=500, default="", blank=True)
summary = models.CharField(max_length=500, default="", blank=True)
serializers.py
class MySourceSerializer(serializers.ModelSerializer):
class Meta:
model = MySource
fields = ("id", "url", "title", "publisher", "desc", "summary")
def to_representation(self, instance):
self.fields["document"] = DocumentSerializer(read_only=True)
return super(MySourceSerializer, self).to_representation(instance)
class DocumentSerializer(serializers.ModelSerializer):
id = HashidSerializerCharField(source_field="documents.Document.id", read_only=True)
question_blocks = QuestionBlockSerializer(many=True)
mysource = MySourceSerializer(many=True)
class Meta:
model = Document
fields = "__all__"
def create(self, validated_data):
question_blocks = validated_data.pop("question_blocks")
document = Document.objects.create(**validated_data)
for qBlock in question_blocks:
QuestionBlock.objects.create(document=document, **qBlock)
document.save()
return document
编辑:添加QuestionBlockSerializer以获取更多上下文
class QuestionBlockSerializer(serializers.ModelSerializer):
document = serializers.PrimaryKeyRelatedField(
pk_field=HashidSerializerCharField(source_field="documents.Document.id"),
read_only=True,
)
class Meta:
model = QuestionBlock
fields = "__all__"
optional_fields = ["content"]
发布于 2022-06-01 23:51:51
我认为做这件事的合适方法可能是这样的:
###imports
from django.forms.models import model_to_dict
class DocumentListingField(serializers.RelatedField):
def to_representation(self, instance):
return model_to_dict(instance.document)
然后在MySourceSerializer中删除to_representation函数并更新如下内容:
class MySourceSerializer(serializers.ModelSerializer):
document = DocumentListingField(many=False, read_only=True)
class Meta:
model = MySource
fields = (
"id", "url", "title", "publisher", "desc", "summary", "document")
*编辑:我将read_only集添加到True,因为这些模型使用的哈希菲尔德并不容易选择。
**编辑:导致响应缓慢的原因是,您有一个循环调用序列化程序,因此系统永远不知道何时停止。就在这里:
class MySourceSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
...
self.fields["document"] = DocumentSerializer(read_only=True)
#Mysource its calling Documentserializer
...
#And here:
class DocumentSerializer(serializers.ModelSerializer):
...
mysource = MySourceSerializer(many=True) #this one its calling the MysorceSerialize, so there are a endless loop recursion
https://stackoverflow.com/questions/72472264
复制