【问题标题】:Sending back file-content instead of href with django-rest-framework?使用 django-rest-framework 发回文件内容而不是 href?
【发布时间】:2020-01-14 16:05:58
【问题描述】:

我有一个文章模型,它带有一个字段FileField,它应该是一个降价文件,供用户加载他们的文章。我用 ModelViewSet 公开了 api。

这已保存到我的媒体文件夹中。我当然可以通过从href 获取内容来从客户端获取内容,但这意味着对我的服务器有 2 个请求:

  1. 获取文章信息(标题、内容 - 这是 md、发布日期、描述等)。
  2. 从链接中获取内容。

但我想知道是否有办法告诉 django 在响应对文章项目的请求时只发送文件内容而不是 href

这是我的模型和 api:

# ---------------------- #
# src/articles/models.py #
# ---------------------- #

from os.path import splitext
from uuid import uuid4
from django.db import models

# Create your models here.


def hashFilename(instance, name):
    ext = splitext(name)[1]
    return "articles/{}{}".format(uuid4(), ext)


def hashImageFilename(instance, name):
    ext = splitext(name)[1]
    return "images/{}{}".format(uuid4(), ext)


class Article(models.Model):
    title = models.CharField(("title"), max_length=100)
    content = models.FileField("content", upload_to=hashFilename)
    description = models.TextField(("description"), default='')
    uploadDate = models.DateTimeField(("uploadDate"), auto_now=True)
    lastModified = models.DateTimeField(("uploadDate"), auto_now=True)
    publicationDate = models.DateField("publicationDate")
    image = models.ImageField("image", upload_to=hashImageFilename)

    def __str__(self):
        return self.title

# ------------------------- #
# src/articles/api/views.py #
# ------------------------- #

from rest_framework.viewsets import ModelViewSet

from ..models import Article
from .serializers import ArticleSerializerFull, ArticleSerializerShort


class ArticlesViewSet(ModelViewSet):
    queryset = Article.objects.all()

    def get_serializer_class(self):
        if self.action == 'list':
            serializer = ArticleSerializerShort
        else:
            serializer = ArticleSerializerFull
        return serializer

    queryset = Article.objects.all()

【问题讨论】:

    标签: python django django-models django-rest-framework


    【解决方案1】:

    定义一个serializers.SerializerMethodField--(DRF Doc) 方法就可以完成这项工作。

    class ArticleSerializer(serializers.ModelSerializer):
        content = serializers.SerializerMethodField()
    
        def get_content(self, article):
            return article.content.file.read()
    
        class Meta:
            fields = '__all__'
            model = Article

    或者,您可以通过覆盖序列化程序的 to_representation 方法来实现相同的目的。

    class ArticleSerializer(serializers.ModelSerializer):
        class Meta:
            fields = '__all__'
            model = Article
    
        def to_representation(self, instance):
            rep = super().to_representation(instance)
            rep['content'] = instance.content.file.read()
            return rep

    更新-1

    来自this comment,我希望您需要Django Admin 中的实时降价编辑器,而不是FileField.

    因此,使用any of these markdown packages 在 Django Admin 中获取实时视图。这些包使用models.TextField 来存储markdown 内容。这样您就可以从 anywhere 中的字段中读取内容,就像任何其他模型字段一样

    【讨论】:

    • 这很棒。唯一的问题是在上传文件后它不会给管理员留下一个编辑 UI。
    • 对不起,我不明白你的担忧。你能再解释一下吗?
    • 我将分解用例:我的用户是网站上的管理员,拥有他的著作。 1. 他在自己的文本编辑器上准备了一篇 MD 格式的文章。 2. 他进入管理页面,创建一篇新文章,并为内容上传 MD 文件。 3. 前端把内容抓取好,直接在网站上展示(经过你的建议更正)。 4. 用户注意到一个问题,他想更新文章——目前他必须去他机器上的文件,更新它,然后上传。如果他可以在管理面板中编辑它会更好。 (我知道这可能有点牵强)。
    • AFAIK,由于此内容与 FileField 相关联,因此您不能 edit 使用 live view i>.
    • 好吧,这些包确实是我想要的!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多