Как вернуть фактические данные файла вместо URL файла из Django Rest Framework FileField объекта - PullRequest
0 голосов
/ 25 марта 2020

Я пытаюсь создать простой API, который возвращает XML данные файла клиенту. Я использую Django 3.0.4 и Django Rest Framework 3.11.0 и основал большую часть своей работы на этом уроке https://www.django-rest-framework.org/tutorial/1-serialization/

Это моя модель:

из django .db импорт моделей

class File(models.Model):
    file = models.FileField(blank=False, null=False)
    device = models.CharField(max_length=20, primary_key=True)

    class Meta:
        verbose_name_plural = "API"

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

Это просмотры:

from django.shortcuts import render
from rest_framework.parsers import FileUploadParser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from .serializers import FileSerializer
from .models import File

class FileList(APIView):
    """
    List all files, or create a new file.
    """
    def post(self, request, format=None):
        serializer = FileSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def get(self, request, format=None):
        files = File.objects.all()
        serializer = FileSerializer(files, many=True)
        return Response(serializer.data)

class FileDetail(APIView):
    """
    Retrieve, update or delete a file instance.
    """

    def get(self, request, pk, format=None):
        file = File.objects.get(pk=pk)
        serializer = FileSerializer(file)
        return Response(serializer.data)

Это URL-адреса приложений:

from django.urls import path
from .views import FileList
from .views import FileDetail
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('<str:pk>', FileDetail.as_view()),
    path('', FileList.as_view()),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

У меня это в НАСТРОЙКАХ:

STATIC_URL = '/static/'
MEDIA_URL = '/path/to/file:devices/'
MEDIA_ROOT = os.path.join(BASE_DIR, "path/to/file:devices")

Все хорошо работает, ошибок не вижу. Я могу POST файл и GET файлы (либо в виде списка, либо в виде отдельного файла, основанного на pk), используя Почтальон. У меня проблема в том, что когда я получаю отдельный файл, я получаю следующее:

{
    "file": "/path/to/file:devices/example.xml",
    "device": "example.xml"
}

Я хочу, чтобы ответом было содержимое файла (фактические XML данные), а не URL-адрес файла. Любые идеи будут оценены.

1 Ответ

0 голосов
/ 08 апреля 2020

OK. Я понял это для себя. Очень просто на самом деле.

Все, что мне нужно было сделать, это перенаправить GET на URL, где хранится фактический файл в структуре файла.

Вот новое представление класса FileDetail:

class FileDetail(APIView):
    """
    Get or delete a file instance.
    """

    def get(self, request, pk, format=None):
        print("hitting detail get")
        response = redirect(os.path.join(settings.MEDIA_URL, (pk +'.xml')))
        return response
...