djangorest:创建新父对象时如何设置相关字段可选
在这里,我有两个模型:文档和Mysource,MySource将文档作为外国关键领域。为了总结该关系,用一个空数阵列的MySource对象初始化了文档,用户可以在其中创建一个新的MySource对象。
我正在尝试找出一种使用以下帖子请求创建文档对象的方法,其中MySource字段在开始时可以选择或空。
POST REQUEST
{
"title": "Untitled",
"templateId": 30,
"question_blocks": [],
"outline_blocks": [],
}
这将给出错误消息:“需要MySource字段”,
POST REQUEST
{
"title": "Untitled",
"templateId": 30,
"question_blocks": [],
"outline_blocks": [],
"mysource": []
}
这将给出错误消息:直接分配到相关集的反向侧。使用adveress.set()而不是
models.py
class Document(models.Model):
id = HashidAutoField(primary_key=True)
# TODO: blank, null to False
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
title = models.CharField(max_length=100, default="Untitled")
template = models.CharField(max_length=100, default="")
editorState = models.JSONField(default=[])
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
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,
)
documentId = models.CharField(max_length=50, default="", blank=True)
url = models.CharField(max_length=500, default="", blank=True)
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 DocumentListingField(serializers.RelatedField):
def to_representation(self, instance):
return model_to_dict(instance.document)
class MySourceSerializer(serializers.ModelSerializer):
Document = DocumentListingField(many=False, read_only=True)
class Meta:
model = MySource
fields = ("id", "url", "title", "publisher", "desc", "summary", "Document")
def create(self, validated_data):
# documentId = validated_data.pop("documentId")
source = MySource.objects.create(
document=Document.objects.get(id="J9DY2pE"), **validated_data
)
print(validated_data)
source.save()
return source
class DocumentSerializer(serializers.ModelSerializer):
id = HashidSerializerCharField(source_field="documents.Document.id", read_only=True)
question_blocks = QuestionBlockSerializer(many=True)
outline_blocks = OutlineBlockSerializer(many=True)
# TODO: disabling mysource until user foreign key is resolved
mysource = MySourceSerializer(many=True)
user = serializers.PrimaryKeyRelatedField(
read_only=True, default=serializers.CurrentUserDefault()
)
class Meta:
model = Document
fields = "__all__"
def create(self, validated_data):
print(validated_data)
question_blocks = validated_data.pop("question_blocks")
outline_blocks = validated_data.pop("outline_blocks")
document = Document.objects.create(**validated_data)
for qBlock in question_blocks:
QuestionBlock.objects.create(document=document, **qBlock)
for oBlock in outline_blocks:
OutlineBlock.objects.create(document=document, **oBlock)
document.save()
return document
Here I have two models: Document and MySource, where MySource has Document as its foreign key field. To summarize the relationship, Document is initialized with an empty array of MySource objects, where a user can later create a new MySource object.
I am trying to figure out a way to create a Document object with the following POST requests with mysource field set either optional or empty in the beginning.
POST REQUEST
{
"title": "Untitled",
"templateId": 30,
"question_blocks": [],
"outline_blocks": [],
}
This will give the error message: "mysource field is required"
POST REQUEST
{
"title": "Untitled",
"templateId": 30,
"question_blocks": [],
"outline_blocks": [],
"mysource": []
}
This will give the error message: Direct assignment to the reverse side of a related set is prohibited. Use addresses.set() instead
models.py
class Document(models.Model):
id = HashidAutoField(primary_key=True)
# TODO: blank, null to False
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
title = models.CharField(max_length=100, default="Untitled")
template = models.CharField(max_length=100, default="")
editorState = models.JSONField(default=[])
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
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,
)
documentId = models.CharField(max_length=50, default="", blank=True)
url = models.CharField(max_length=500, default="", blank=True)
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 DocumentListingField(serializers.RelatedField):
def to_representation(self, instance):
return model_to_dict(instance.document)
class MySourceSerializer(serializers.ModelSerializer):
Document = DocumentListingField(many=False, read_only=True)
class Meta:
model = MySource
fields = ("id", "url", "title", "publisher", "desc", "summary", "Document")
def create(self, validated_data):
# documentId = validated_data.pop("documentId")
source = MySource.objects.create(
document=Document.objects.get(id="J9DY2pE"), **validated_data
)
print(validated_data)
source.save()
return source
class DocumentSerializer(serializers.ModelSerializer):
id = HashidSerializerCharField(source_field="documents.Document.id", read_only=True)
question_blocks = QuestionBlockSerializer(many=True)
outline_blocks = OutlineBlockSerializer(many=True)
# TODO: disabling mysource until user foreign key is resolved
mysource = MySourceSerializer(many=True)
user = serializers.PrimaryKeyRelatedField(
read_only=True, default=serializers.CurrentUserDefault()
)
class Meta:
model = Document
fields = "__all__"
def create(self, validated_data):
print(validated_data)
question_blocks = validated_data.pop("question_blocks")
outline_blocks = validated_data.pop("outline_blocks")
document = Document.objects.create(**validated_data)
for qBlock in question_blocks:
QuestionBlock.objects.create(document=document, **qBlock)
for oBlock in outline_blocks:
OutlineBlock.objects.create(document=document, **oBlock)
document.save()
return document
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您需要将
read_only = true
属性添加到mySource
字段中。I think you need to add
read_only=True
attribute into themysource
field.