【问题标题】:How to step wise post data to an object using the Django-Rest Framework?如何使用 Django-Rest 框架逐步将数据发布到对象?
【发布时间】:2020-11-14 21:02:31
【问题描述】:

我想将一个带有 Django-Rest 框架的对象发布到我的后端。该对象包含多个嵌套对象,用户通过 React JS 前端逐个插入此信息。

class Story (models.Model):
    title = models.CharField(max_length=100,blank=False)
    content = models.TextField(blank=False)
    date_posted = models.DateTimeField(default=timezone.now)
    place = models.ForeignKey(Place, on_delete=models.PROTECT, null=True)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
    images = models.FileField(upload_to='audio_stories/',validators=[validate_file_extension_image], 
    blank=False)
    audio = models.FileField(upload_to='audio_stories/',validators=[validate_file_extension_audio], blank=False)

我现在想知道如何逐步将数据发送到服务器。有没有办法在创建过程的一开始就启动故事对象以生成其主键,然后逐步将其他数据添加到该键中,例如图像和音频?我已经在 Django 文档中搜索了正确的术语,但我在处理这个主题时遇到了困难。

我很高兴得到任何澄清。

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    只需为您的Story 创建多个端点和序列化程序:

    class StoryBaseSerializer(serializers.ModelSerializer):
        title = serializers.CharField(...)
        date_posted = serializers.DateTimeField(auto_now=True)
        id = serializers.ReadOnlyField()
        
            class Meta:
                model = models.Story
                fields = ['title', 'date_posted', 'id']
    
    class StoryContentSerializer(serializers.ModelSerializer):
        content = serializers.TextField(...)
        images = serializers.ImageField(...)
        id = serializers.ReadOnlyField()
        
            class Meta:
                model = models.Story
                fields = ['content', 'images', 'id']
    #and so on
    

    然后,创建端点:

    # e.G. /api/v1/stories
    
    CreateStoryView(views.ListCreateAPIView):
        serializer_class = StoryBaseSerializer
        # standard api code....
    

    然后是修改Story 对象的视图:

    # e.G. /api/v1/stories/content/<int:pk>
    UpdateStoryContent(views.UpdateAPIView):
        serializer_class = StoryBaseSerializer
        
        def get_object(self):
            story_id= self.kwargs['pk']
            story = get_object_or_404(self.get_queryset(), id=story_id)
            return story;
    
    #and a view for each serializer you have defined.
    

    当然,另一种(也许更优雅的方式)是定义第二个序列化程序(除了StoryBaseSerializer),它使所有字段都是可选的(非必需的,只需在序列化程序中设置required 标志字段到False) 并使用设置的字段更新Story 数据。

    类似这样的事情:

    class UpdateStorySerializer(serializers.ModelSerializer):
        content = serializers.TextField(required=False, ...)
        images = serializers.ImageField(required=False...)
        # all your other fields go here
        id = serializers.ReadOnlyField()
        
        class Meta:
            model = models.Story
            fields = ['title', 'date_posted', '...', 'id']
    

    然后创建一个单独的更新视图,与上面相同,但可能在另一个端点,比如api/v1/stories/&lt;int:pk&gt;。现在,在您的反应视图中,您只需发布您想要更新的数据。比如你发帖到api/v1/stories/17

    {
       "content" : "... the content ...."
    }
    

    或:

    {
       "audio" : "blob data of your audio file"
    }
    

    这只会更新 id 为 17 的故事内容。

    【讨论】:

    • 非常感谢您的回答!它让我朝着正确的方向前进。当用户退出故事创建过程而不输入所有数据时会发生什么,这对我产生了一个问题。我的数据库中的故事是否“完成了一半”?
    • 嗯,是的。但是你可以很容易地解决这个问题。您只提供一个端点,一个简单的 POST 端点。您在前端引导用户完成创建过程,将所有中间信息存储在那里。只有当故事完成(完成)时,您才会对端点进行完整的 POST。想想facebook(可能)是如何做到这一点的......你真的认为他们一开始输入就创建了一个数据库条目吗?当您点击“发布”时,他们会点击数据库。以后可以通过 PUT 或 PATCH 设置故事的所有可选内容。仅在所有内容时创建(发布)故事......
    猜你喜欢
    • 2023-04-03
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    相关资源
    最近更新 更多