首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何使用外键发布和获取模型

如何使用外键发布和获取模型
EN

Stack Overflow用户
提问于 2022-06-02 07:27:49
回答 1查看 205关注 0票数 0

我正在从事一个NextJS + Django REST框架项目,其中有三个模型: Document、MySource和QuestionBlock。

  1. 文档与几个链接到所创建文档的“question_blocks”一起创建。它们是一起创建的,我已经用嵌套序列化器实现了这一点。
  2. 创建文档后,我希望能够发布链接到文档的MySource模型。然后,当我对文档发出GET请求时,还应该显示所有mysource对象。

POST请求:注意我如何将文档的id放在我想要链接的.

代码语言:javascript
代码运行次数:0
运行
复制
{
  "url": "urlasdf",
  "title": "tuitle",
  "publisher": "afdfas ",
  "desc": "qwefqwef",
  "summary": "asdfasdf",
  "document": "J9DY2pE"
}

GET请求:我希望文档GET请求显示如下所示。

代码语言:javascript
代码运行次数:0
运行
复制
"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

代码语言:javascript
代码运行次数:0
运行
复制
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

代码语言:javascript
代码运行次数:0
运行
复制
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以获取更多上下文

代码语言:javascript
代码运行次数:0
运行
复制
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"]
EN

回答 1

Stack Overflow用户

发布于 2022-06-02 07:51:51

我认为做这件事的合适方法可能是这样的:

代码语言:javascript
代码运行次数:0
运行
复制
###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函数并更新如下内容:

代码语言:javascript
代码运行次数:0
运行
复制
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,因为这些模型使用的哈希菲尔德并不容易选择。

**编辑:导致响应缓慢的原因是,您有一个循环调用序列化程序,因此系统永远不知道何时停止。就在这里:

代码语言:javascript
代码运行次数:0
运行
复制
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

来源:Django Rest框架-自定义关系字段

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72472264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档