如何通过 Django REST 向 RichTextUploadField 添加图像或音频文件上传支持?

How to add an image or an audio file upload support to RichTextUploadField through Django REST?

我的模型中有一个由 ckeditor 的库添加的 RichTextUploadField。我想添加一个支持来创建简单的 html 字段相关内容,其中包括一些 imgaudio 标签。我已经添加了通过管理员上传 html 内容的支持只是不知道如何添加通过 API 端点创建的支持?

models.py

from ckeditor_uploader.fields import RichTextUploadingField

class Part(models.Model):
    title = models.CharField(max_length=255)
    textfield = RichTextUploadingField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-created_at', )

    def __str__(self):
        return str(self.explanation)

settings.py!部分

...
INSTALLED_APPS = [
    ...
    # third party installed apps
    'rest_framework',
    'ckeditor',
    'ckeditor_uploader',
    ...
]

CKEDITOR_UPLOAD_PATH = "uploads/"
...
### I am using html5audio package to upload audios
CKEDITOR_CONFIGS = {
    'default': {
        'toolbar': 'full',
        'extraPlugins': ','.join(
            [
                'html5audio',
            ]
        ),
    },
}

问题:如何添加支持以通过 REST API 端点创建 HTML 内容?

我认为你应该实现两个不同的端点,你可以上传音频或图像文件。请注意,您应该将 upload_to 配置为 ckeditor 可以访问的文件夹。按照我的自定义实现来满足您的要求。

models.py

from django.db import models

import os
from uuid import uuid4


def get_custom_audio_upload_path(filename, instance):
    ext = str(filename).split('.')[-1]
    filename = f'{uuid4()}.{ext}'
    return os.path.join("uploads/custom_audio/", filename)


def get_custom_image_upload_path(filename, instance):
    ext = str(filename).split('.')[-1]
    filename = f'{uuid4()}.{ext}'
    return os.path.join("uploads/custom_image/", filename)


class CustomAudio(models.Model):
    audio = models.FileField(upload_to=get_custom_audio_upload_path)

    def __str__(self):
        return self.audio.name


class CustomImage(models.Model):
    image = models.ImageField(upload_to=get_custom_image_upload_path)

    def __str__(self):
        return self.image.name

serializers.py

class CustomAudioSerializer(ModelSerializer):
    class Meta:
        model = CustomAudio
        fields = '__all__'


class CustomImageSerializer(ModelSerializer):
    class Meta:
        model = CustomImage
        fields = '__all__'

views.py

...

class CustomAudioViewSet(ModelViewSet):
    queryset = CustomAudio.objects.all()
    serializer_class = CustomAudioSerializer
    permission_classes = [IsAdminUser, ]

    def create(self, request, *args, **kwargs):
        data = request.data
        serialized = CustomAudioSerializer(data=data)
        if serialized.is_valid():
            serialized.save()
            return Response(serialized.data, status=status.HTTP_201_CREATED)
        return Response(serialized.errors, status=status.HTTP_400_BAD_REQUEST)

    def get_permissions(self):
        if self.action == "list" or self.action == "retrieve":
            permission_classes = [AllowAny, ]
        else:
            permission_classes = [AllowAny, ]
        return [permission() for permission in permission_classes]


class CustomImageViewSet(ModelViewSet):
    queryset = CustomImage.objects.all()
    serializer_class = CustomImageSerializer
    permission_classes = [IsAdminUser]

    def create(self, request, *args, **kwargs):
        data = request.data
        serialized = CustomAudioSerializer(data=data)
        if serialized.is_valid():
            serialized.save()
            return Response(serialized.data, status=status.HTTP_201_CREATED)
        return Response(serialized.errors, status=status.HTTP_400_BAD_REQUEST)

    def get_permissions(self):
        if self.action == "list" or self.action == "retrieve":
            permission_classes = [AllowAny, ]
        else:
            permission_classes = [AllowAny, ]
        return [permission() for permission in permission_classes]

urls.py

from rest_framework.routers import SimpleRouter
from django.urls import path, include
from someapp.views import CustomImageViewSet, CustomAudioViewSet

router = SimpleRouter()
router.register('customaudio', CustomAudioViewSet)
router.register('customimage', CustomImageViewSet)

urlpatterns = [
    path('', include(router.urls)
]

稍微解释一下:当您上传音频或图像时,您应该向端点发出 post 请求,您将获得 url 结果并将其嵌入到标签中。它应该从您的媒体文件夹中检索它。