Django Rest Framework 파일 업로드


100

Django Rest Framework와 AngularJs를 사용하여 파일을 업로드하고 있습니다. 내보기 파일은 다음과 같습니다.

class ProductList(APIView):
    authentication_classes = (authentication.TokenAuthentication,)
    def get(self,request):
        if request.user.is_authenticated(): 
            userCompanyId = request.user.get_profile().companyId
            products = Product.objects.filter(company = userCompanyId)
            serializer = ProductSerializer(products,many=True)
            return Response(serializer.data)

    def post(self,request):
        serializer = ProductSerializer(data=request.DATA, files=request.FILES)
        if serializer.is_valid():
            serializer.save()
            return Response(data=request.DATA)

post 메소드의 마지막 줄은 모든 데이터를 반환해야하므로 몇 가지 질문이 있습니다.

  • 에 아무것도 있는지 확인하는 방법 request.FILES?
  • 파일 필드를 직렬화하는 방법?
  • 파서를 어떻게 사용해야합니까?

13
MOD에 대한 참고 사항 : Django는 2013 년 이후 크게 업그레이드되었습니다. 다른 사람이 지금 같은 질문을 게시한다면. 그들을 격추하지 마세요 ^ _ ^.
Jessi

Base64는 어떻습니까?
Hojat Modaresi

답변:


68

FileUploadParser를 사용하면 모두 요청에 포함됩니다. 대신 put 메서드를 사용하면 문서에서 예제를 찾을 수 있습니다. :)

class FileUploadView(views.APIView):
    parser_classes = (FileUploadParser,)

    def put(self, request, filename, format=None):
        file_obj = request.FILES['file']
        # do some stuff with uploaded file
        return Response(status=204)

12
@pleasedontbelong 왜 여기에서 POST 대신 PUT 메서드가 사용 되었습니까?
. 메릴랜드 Tanvir Raihan

8
안녕하세요 @pleasedontbelong, 새 레코드를 만드는 경우 대신 POST가 될까요? 여전히 FileUploadParser와 함께 작동합니까?
chrizonline

1
@pleasedontbelong RTan은 꽤 좋은 질문을합니다. RFC-2616을 읽으면 지금까지 알지 못했던 미묘함이 있습니다. "POST 요청과 PUT 요청의 근본적인 차이점은 Request-URI의 다른 의미에 반영됩니다. POST 요청의 URI는 포함 된 엔티티를 처리 할 리소스를 식별합니다. 해당 리소스는 데이터 수락 프로세스 인 게이트웨이 일 수 있습니다. . 「대조적으로, URI는 PUT 요청에서 식별 엔티티가 상기 요청에 첨부 다른 프로토콜, 또는 주석을 수락하는 별개의 실체
dudeman

3
왜 FileUploadParser인가? "FileUploadParser는 원시 데이터 요청으로 파일을 업로드 할 수있는 기본 클라이언트와 함께 사용하기위한 것입니다. 웹 기반 업로드 또는 멀티 파트 업로드 지원이있는 기본 클라이언트의 경우 대신 MultiPartParser 파서를 사용해야합니다." 일반적으로 좋은 옵션처럼 보이지 않습니다. 또한 특정 처리 가 필요한 파일 업로드가 표시되지 않습니다 .
x-yuri

3
두 번째 @ x-yuri에게 DRF는 FileUploadParser를 사용할 때 Content-Disposition 헤더가 비어 있다고 불평합니다. MultiPartParser는 파일 이름이 양식 필드에 지정된 파일 이름이라고 가정하기 때문에 훨씬 간단합니다.
David Zwart

74

동일한 스택을 사용하고 있으며 파일 업로드의 예를 찾고 있었지만 APIView 대신 ModelViewSet을 사용하기 때문에 제 경우가 더 간단합니다. 열쇠는 pre_save 훅으로 밝혀졌습니다. 나는 다음과 같이 angular-file-upload 모듈과 함께 사용하게되었습니다.

# Django
class ExperimentViewSet(ModelViewSet):
    queryset = Experiment.objects.all()
    serializer_class = ExperimentSerializer

    def pre_save(self, obj):
        obj.samplesheet = self.request.FILES.get('file')

class Experiment(Model):
    notes = TextField(blank=True)
    samplesheet = FileField(blank=True, default='')
    user = ForeignKey(User, related_name='experiments')

class ExperimentSerializer(ModelSerializer):
    class Meta:
        model = Experiment
        fields = ('id', 'notes', 'samplesheet', 'user')

// AngularJS
controller('UploadExperimentCtrl', function($scope, $upload) {
    $scope.submit = function(files, exp) {
        $upload.upload({
            url: '/api/experiments/' + exp.id + '/',
            method: 'PUT',
            data: {user: exp.user.id},
            file: files[0]
        });
    };
});

11
pre_save IS되지 않는에서 DRF 3.X
가이 S

내 경험상 파일 필드에 특별한 처리가 필요 하지 않습니다 .
x-yuri

@ Guy-S, perform_create, perform_update, perform_destroy 메소드는 더 이상 사용할 수없는 이전 스타일 버전 2.x pre_save, post_save, pre_delete 및 post_delete 메소드를 대체
Rufat

38

마지막으로 Django를 사용하여 이미지를 업로드 할 수 있습니다. 내 작업 코드는 다음과 같습니다.

views.py

class FileUploadView(APIView):
    parser_classes = (FileUploadParser, )

    def post(self, request, format='jpg'):
        up_file = request.FILES['file']
        destination = open('/Users/Username/' + up_file.name, 'wb+')
        for chunk in up_file.chunks():
            destination.write(chunk)
        destination.close()  # File should be closed only after all chuns are added

        # ...
        # do some stuff with uploaded file
        # ...
        return Response(up_file.name, status.HTTP_201_CREATED)

urls.py

urlpatterns = patterns('', 
url(r'^imageUpload', views.FileUploadView.as_view())

업로드 요청 컬

curl -X POST -S -H -u "admin:password" -F "file=@img.jpg;type=image/jpg" 127.0.0.1:8000/resourceurl/imageUpload

14
왜 destination.close ()가 for 루프 내부에 배치됩니까?
makerj

12
그것을 사용하는 것이 좋습니다 것 같다 with open('/Users/Username/' + up_file.name, 'wb+') as destination:전적으로 가까운을 제거
척 윌버에게

사용하는 것이 더 간단합니다 ModelViewSet. 또한 그들은 그것을 더 잘 구현했을 가능성이 큽니다.
x-yuri

나는 하루 종일이 응답자에 의존해 왔습니다 ... 여러 파일을 업로드하고 싶을 때 FileUploadParser필요한 것은 아니지만 MultiPartParser!
Olivier Pons

13

이것에 하루를 보낸 후 나는 그것을 알아 냈습니다 ...

파일을 업로드하고 일부 데이터를 보내야하는 사람에게는 파일을 작동시킬 수있는 직접적인 방법이 없습니다. 이에 대한 json api 사양에 미해결 문제 가 있습니다. 내가 본 한 가지 가능성은 여기multipart/related표시된 것처럼 사용 하는 것이지만 drf에서 구현하기가 매우 어렵다고 생각합니다.

마지막으로 구현 한 것은 요청을 formdata. 각 파일은 파일로 , 다른 모든 데이터는 텍스트 로 보냅니다 . 이제 데이터를 텍스트로 보내기 위해 두 가지 선택이 있습니다. 경우 1) 각 데이터를 키 값 쌍으로 보낼 수 있습니다. 또는 경우 2) data 라는 단일 키를 가지고 전체 json을 값의 문자열로 보낼 수 있습니다 .

첫 번째 방법은 간단한 필드가있는 경우 즉시 작동하지만 중첩 된 직렬화가있는 경우 문제가됩니다. 멀티 파트 구문 분석기는 중첩 된 필드를 구문 분석 할 수 없습니다.

아래에서는 두 경우 모두에 대한 구현을 제공하고 있습니다.

Models.py

class Posts(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    caption = models.TextField(max_length=1000)
    media = models.ImageField(blank=True, default="", upload_to="posts/")
    tags = models.ManyToManyField('Tags', related_name='posts')

serializers.py-> 특별한 변경이 필요하지 않습니다. 쓰기 가능한 ManyToMany 필드 구현으로 인해 여기에 내 serializer가 너무 긴 것으로 표시되지 않습니다.

views.py

class PostsViewset(viewsets.ModelViewSet):
    serializer_class = PostsSerializer
    #parser_classes = (MultipartJsonParser, parsers.JSONParser) use this if you have simple key value pair as data with no nested serializers
    #parser_classes = (parsers.MultipartParser, parsers.JSONParser) use this if you want to parse json in the key value pair data sent
    queryset = Posts.objects.all()
    lookup_field = 'id'

이제 첫 번째 방법을 따르고 비 JSON 데이터 만 키 값 쌍으로 보내는 경우 사용자 지정 파서 클래스가 필요하지 않습니다. DRF의 MultipartParser가 작업을 수행합니다. 그러나 두 번째 경우 또는 중첩 된 직렬 변환기가있는 경우 (내가 보여준 것처럼) 아래와 같이 사용자 정의 파서가 필요합니다.

utils.py

from django.http import QueryDict
import json
from rest_framework import parsers

class MultipartJsonParser(parsers.MultiPartParser):

    def parse(self, stream, media_type=None, parser_context=None):
        result = super().parse(
            stream,
            media_type=media_type,
            parser_context=parser_context
        )
        data = {}

        # for case1 with nested serializers
        # parse each field with json
        for key, value in result.data.items():
            if type(value) != str:
                data[key] = value
                continue
            if '{' in value or "[" in value:
                try:
                    data[key] = json.loads(value)
                except ValueError:
                    data[key] = value
            else:
                data[key] = value

        # for case 2
        # find the data field and parse it
        data = json.loads(result.data["data"])

        qdict = QueryDict('', mutable=True)
        qdict.update(data)
        return parsers.DataAndFiles(qdict, result.files)

이 serializer는 기본적으로 값의 모든 json 콘텐츠를 구문 분석합니다.

두 경우 모두에 대한 post man의 요청 예 : case 1 사례 1,

사례 2 사례 2


차라리 사례 2를 피하고 싶습니다. 요청 당 하나의 데이터베이스 레코드를 만드는 것이 대부분의 경우 괜찮습니다.
x-yuri

매우 도움이되었습니다. 감사합니다. 하지만 이해가 안 돼요, 왜 dict 데이터를 파서에서 QueryDict로 변환하고 있습니까? Django의 경우 일반 사전 데이터는 변환없이 완벽하게 작동합니다.
Metehan Gülaç

언급 한 답변을 사용하여 다른 시나리오를 시도했으며 성공적으로 작동합니다. 당신은 나의 대답을 .
Metehan Gülaç

이것이 작동하면 stackoverflow.com/questions/64547729/… 도 작동 해야하지만 작동하지 않습니다.
sadat

9

제 경험상 파일 필드에 대해 특별히 할 필요는 없습니다. 파일 필드를 사용하라고 말하면됩니다.

from rest_framework import routers, serializers, viewsets

class Photo(django.db.models.Model):
    file = django.db.models.ImageField()

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

class PhotoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Photo
        fields = ('id', 'file')   # <-- HERE

class PhotoViewSet(viewsets.ModelViewSet):
    queryset = models.Photo.objects.all()
    serializer_class = PhotoSerializer

router = routers.DefaultRouter()
router.register(r'photos', PhotoViewSet)

api_urlpatterns = ([
    url('', include(router.urls)),
], 'api')
urlpatterns += [
    url(r'^api/', include(api_urlpatterns)),
]

파일을 업로드 할 준비가되었습니다.

curl -sS http://example.com/api/photos/ -F 'file=@/path/to/file'

추가 -F field=value모델이있는 각 여분 필드. 그리고 인증을 추가하는 것을 잊지 마십시오.


7

ModelViewSet 및 ModelSerializer로이 문제를 해결했습니다. 이것이 커뮤니티에 도움이되기를 바랍니다.

또한 뷰가 아닌 serializer 자체에서 유효성 검사 및 Object-> JSON (또는 그 반대) 로그인을 선호합니다.

예를 들어 이해합시다.

FileUploader API를 만들고 싶습니다. id, file_path, file_name, size, owner 등과 같은 필드를 데이터베이스에 저장할 위치입니다. 아래 샘플 모델을 참조하십시오.

class FileUploader(models.Model):
    file = models.FileField()
    name = models.CharField(max_length=100) #name is filename without extension
    version = models.IntegerField(default=0)
    upload_date = models.DateTimeField(auto_now=True, db_index=True)
    owner = models.ForeignKey('auth.User', related_name='uploaded_files')
    size = models.IntegerField(default=0)

이제 API의 경우 이것이 내가 원하는 것입니다.

  1. 가져 오기:

GET 엔드 ​​포인트를 실행할 때 업로드 된 모든 파일에 대해 위의 모든 필드를 원합니다.

  1. 게시하다:

하지만 사용자가 파일을 생성 / 업로드하기 위해이 모든 필드를 전달하는 것에 대해 걱정해야하는 이유입니다. 그녀는 파일을 업로드하기 만하면 직렬화 기가 업로드 된 FILE에서 나머지 필드를 가져올 수 있습니다.

Searilizer : 질문 : 내 목적을 달성하기 위해 아래에 serializer를 만들었습니다. 그러나 그것을 구현하는 올바른 방법인지 확실하지 않습니다.

class FileUploaderSerializer(serializers.ModelSerializer):
    # overwrite = serializers.BooleanField()
    class Meta:
        model = FileUploader
        fields = ('file','name','version','upload_date', 'size')
        read_only_fields = ('name','version','owner','upload_date', 'size')

   def validate(self, validated_data):
        validated_data['owner'] = self.context['request'].user
        validated_data['name'] = os.path.splitext(validated_data['file'].name)[0]
        validated_data['size'] = validated_data['file'].size
        #other validation logic
        return validated_data

    def create(self, validated_data):
        return FileUploader.objects.create(**validated_data)

참조 용 뷰셋 :

class FileUploaderViewSet(viewsets.ModelViewSet):
    serializer_class = FileUploaderSerializer
    parser_classes = (MultiPartParser, FormParser,)

    # overriding default query set
    queryset = LayerFile.objects.all()

    def get_queryset(self, *args, **kwargs):
        qs = super(FileUploaderViewSet, self).get_queryset(*args, **kwargs)
        qs = qs.filter(owner=self.request.user)
        return qs

FileUploaderSerializer.validate메서드에는 어떤 유효성 검사 논리가 포함됩니까?
x-yuri 19

6

Django Rest Framework 용 ModelViewset을 사용하는 가장 쉬운 예제에 관심이있는 사람이 있다면.

모델은

class MyModel(models.Model):
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)
    imageUrl = models.FileField(db_column='image_url', blank=True, null=True, upload_to='images/')

    class Meta:
        managed = True
        db_table = 'MyModel'

직렬 변환기,

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = "__all__"

그리고보기는,

class MyModelView(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

Postman에서 테스트,

여기에 이미지 설명 입력


그리고 ajax를 사용하여 어떻게 요청을 보낼 수 있습니까? 실제로 imageUrl은 무엇입니까?
Eduard Grigoryev

imageUrl은 요청의 파일입니다.
sadat

1
def post(self,request):
        serializer = ProductSerializer(data=request.DATA, files=request.FILES)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)

0

django-rest-framework에서 요청 데이터는 Parsers.
http://www.django-rest-framework.org/api-guide/parsers/

기본적으로 django-rest-framework는 파서 클래스를 사용 JSONParser합니다. 데이터를 json으로 구문 분석합니다. 따라서 파일이 파싱되지 않습니다.
파일을 다른 데이터와 함께 파싱하려면 아래 파서 클래스 중 하나를 사용해야합니다.

FormParser
MultiPartParser
FileUploadParser

현재 버전의 DRF 3.8.2에서는 기본적 application/json으로 application/x-www-form-urlencoded, 및 multipart/form-data.
liquidki

0
    from rest_framework import status
    from rest_framework.response import Response
    class FileUpload(APIView):
         def put(request):
             try:
                file = request.FILES['filename']
                #now upload to s3 bucket or your media file
             except Exception as e:
                   print e
                   return Response(status, 
                           status.HTTP_500_INTERNAL_SERVER_ERROR)
             return Response(status, status.HTTP_200_OK)

0

더 깔끔하고 유지하기 쉬운 또 다른 옵션을 작성하고 싶습니다. defaultRouter를 사용하여 뷰 세트에 CRUD URL을 추가하고 동일한 뷰 세트 내에서 업 로더 뷰를 지정하는 고정 URL을 하나 더 추가 할 것입니다.

**** views.py 

from rest_framework import viewsets, serializers
from rest_framework.decorators import action, parser_classes
from rest_framework.parsers import JSONParser, MultiPartParser
from rest_framework.response import Response
from rest_framework_csv.parsers import CSVParser
from posts.models import Post
from posts.serializers import PostSerializer     


class PostsViewSet(viewsets.ModelViewSet):

    queryset = Post.objects.all()
    serializer_class = PostSerializer 
    parser_classes = (JSONParser, MultiPartParser, CSVParser)


    @action(detail=False, methods=['put'], name='Uploader View', parser_classes=[CSVParser],)
    def uploader(self, request, filename, format=None):
        # Parsed data will be returned within the request object by accessing 'data' attr  
        _data = request.data

        return Response(status=204)

프로젝트의 기본 urls.py

**** urls.py 

from rest_framework import routers
from posts.views import PostsViewSet


router = routers.DefaultRouter()
router.register(r'posts', PostsViewSet)

urlpatterns = [
    url(r'^posts/uploader/(?P<filename>[^/]+)$', PostsViewSet.as_view({'put': 'uploader'}), name='posts_uploader')
    url(r'^', include(router.urls), name='root-api'),
    url('admin/', admin.site.urls),
]

.- 읽어보기.

마법은 클래스 메소드 'uploader'에 @action 데코레이터를 추가 할 때 발생합니다. "methods = [ 'put']"인수를 지정하면 PUT 요청 만 허용됩니다. 파일 업로드에 적합합니다.

또한 "parser_classes"인수를 추가하여 콘텐츠를 구문 분석 할 파서를 선택할 수 있음을 보여줍니다. 이 기능이 필요한 경우 특정 유형의 파일 만 허용하는 방법을 보여주기 위해 rest_framework_csv 패키지에서 CSVParser를 추가했습니다. 제 경우에는 "Content-Type : text / csv"만 허용합니다. 참고 : 사용자 지정 파서를 추가하는 경우 요청이 업 로더 메서드 파서에 액세스하기 전에 허용 된 media_type을 기본 (클래스) 파서와 비교하므로 ViewSet의 parsers_classes에서 지정해야합니다.

이제 Django에게이 메서드로 이동하는 방법과 URL에서 구현할 수있는 위치를 알려야합니다. 이때 고정 URL을 추가합니다 (단순한 목적). 이 URL은 나중에 메서드에서 전달 될 "파일 이름"인수를받습니다. 이 메서드 "uploader"를 전달하여 목록에 http 프로토콜 ( 'PUT')을 지정하여 PostsViewSet.as_view 메서드에 전달해야합니다.

다음 URL에 도착하면

 http://example.com/posts/uploader/ 

"Content-Type"및 Content-Disposition : attachment를 지정하는 헤더가있는 PUT 요청을 예상합니다. filename = "something.csv"입니다.

curl -v -u user:pass http://example.com/posts/uploader/ --upload-file ./something.csv --header "Content-type:text/csv"

따라서 파일을 업로드 한 다음 일부 db 레코드에 첨부하는 것이 좋습니다. 어떤 이유로 연결이 발생하지 않으면 어떻게됩니까? 한 번의 요청으로하지 않겠습니까? parser_classes업로드 할 수있는 파일을 제한하지 않습니다. 요청을하는 데 사용할 수있는 형식을 결정할 수 있습니다. 다시 생각해 보면 업로드를 처리하는 방법은 ... CSV의 데이터를 데이터베이스에 넣는 것 같습니다. OP가 요청한 것이 아닙니다.
x-yuri 19

@ x-yuri는 "CSV는 파일입니다"라고 말하고 질문은 다음과 같습니다. 요청에 데이터가 있는지 확인하는 방법은 무엇입니까? 이 방법을 사용하면 request.data에서 데이터를 찾을 수 있습니다. _data = request.data due PUT이 사용되고 있습니다. 말했듯이 parser_classes는 원하지 않는 다른 형식을 사용하여 요청을 만드는 데 사용할 수있는 형식을 결정하고 추가 보안 레이어를 추가하여 제외됩니다. 귀하의 데이터로 무엇을할지는 귀하에게 달려 있습니다. "Try Except"를 사용하면 "첨부되지 않음"여부를 확인할 수 있으므로 그럴 필요가 없습니다. 코드가하는 일이 아닙니다. 이것들은 1 개의 요청으로 이루어집니다
Wolfgang Leon 19

0

이것이 제가 적용한 접근 방식 중 하나입니다.

     class Model_File_update(APIView):
         parser_classes = (MultiPartParser, FormParser)
         permission_classes = [IsAuthenticated]  # it will check if the user is authenticated or not
         authentication_classes = [JSONWebTokenAuthentication]  # it will authenticate the person by JSON web token

         def put(self, request):
            id = request.GET.get('id')
            obj = Model.objects.get(id=id)
            serializer = Model_Upload_Serializer(obj, data=request.data)
            if serializer.is_valid():
               serializer.save()
               return Response(serializer.data, status=200)
            else:
               return Response(serializer.errors, status=400)

0

@Nithin의 답변을 일반화하여 DRF의 기존 직렬 변환기 시스템과 직접 작업 할 수 있습니다. 파서 클래스를 생성하여 특정 필드를 구문 분석 한 다음 표준 DRF 직렬 변환기에 직접 공급할 수 있습니다.

from django.http import QueryDict
import json
from rest_framework import parsers


def gen_MultipartJsonParser(json_fields):
    class MultipartJsonParser(parsers.MultiPartParser):

        def parse(self, stream, media_type=None, parser_context=None):
            result = super().parse(
                stream,
                media_type=media_type,
                parser_context=parser_context
            )
            data = {}
            # find the data field and parse it
            qdict = QueryDict('', mutable=True)
            for json_field in json_fields:
                json_data = result.data.get(json_field, None)
                if not json_data:
                    continue
                data = json.loads(json_data)
                if type(data) == list:
                    for d in data:
                        qdict.update({json_field: d})
                else:
                    qdict.update({json_field: data})

            return parsers.DataAndFiles(qdict, result.files)

    return MultipartJsonParser

다음과 같이 사용됩니다.

class MyFileViewSet(ModelViewSet):
    parser_classes = [gen_MultipartJsonParser(['tags', 'permissions'])]
    #                                           ^^^^^^^^^^^^^^^^^^^
    #                              Fields that need to be further JSON parsed
    ....

0

ModelViewSet을 사용하고 있다면 실제로 완료되었습니다! 그것은 당신을 위해 모든 것을 처리합니다! ModelSerializer에 필드를 넣고 설정하기 만하면됩니다.content-type=multipart/form-data; 클라이언트에 됩니다.

하지만 아시다시피 json 형식으로 파일을 보낼 수 없습니다. (content-type이 클라이언트에서 application / json으로 설정된 경우). Base64 형식을 사용하지 않는 한.

따라서 두 가지 선택이 있습니다.

  • 하자 ModelViewSetModelSerializer 작업을 처리하고 사용하여 요청을 보내content-type=multipart/form-data;
  • 필드를 ModelSerializer로 설정하고 Base64ImageField (or) Base64FileField클라이언트에게 파일을 인코딩 Base64하고content-type=application/json

0

models.py

from django.db import models

import uuid

class File(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    file = models.FileField(blank=False, null=False)
    
    def __str__(self):
        return self.file.name

serializers.py

from rest_framework import serializers
from .models import File

class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        fields = "__all__"

views.py

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


class FileUploadView(APIView):
    permission_classes = []
    parser_class = (FileUploadParser,)

    def post(self, request, *args, **kwargs):

      file_serializer = FileSerializer(data=request.data)

      if file_serializer.is_valid():
          file_serializer.save()
          return Response(file_serializer.data, status=status.HTTP_201_CREATED)
      else:
          return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

urls.py

from apps.files import views as FileViews

urlpatterns = [
    path('api/files', FileViews.FileUploadView.as_view()),
]

settings.py

# file uload parameters
MEDIA_URL =  '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

필드에 api/files파일을 첨부 하여에 게시 요청을 보냅니다 . 파일이 폴더에 업로드되고 db 레코드가 ID 및 파일 이름과 함께 추가됩니다.form-datafile/media

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.