Django

[Django] 파일 업로드 테스트 with Nginx, uWSGI

chief 2022. 7. 25. 18:00
반응형

🚀  들어가며...

  • 저번 포스팅에서 장고에서의 static files를 다루는 방법에 대해 알아보았습니다. 이번 포스팅에서는 실제로 파일 업로드를 nginx와 uswgi를 이용하여 실행해보고 기록해보았습니다.

 

📑 내용

Django 에서 파일(이미지)를 업로드하기 위해서는 FileField 또는 ImageField 를 사용하면 됩니다. 실제 rest_framework 를 사용하여 테스트했보았습니다.

Django Test Project 만들기

테스트를 위해 간단한 프로젝트를 만듭니다. (Pycharm 을 사용한다면 더 쉽게 프로젝트를 만들 수 있습니다.)

$ django-admin.py startproject firstsite
 

주로 Django project 에서는 startapp 명령어를 통해 app 을 만든다음 application 단위로 코딩을 하지만 저는 Django Project 를 만드는게 목적이 아니므로 app 을 따로 만들지 않고 project 에서 바로 테스트를 할 것입니다. (db 또한 Django 에서 제공하는 sqlite3 을 사용할 것입니다.)

settings.py 작성하기

MEDIA_ROOT = '/home/attachement'
MEDIA_URL = '/media/'


# 파일업로드 사이즈의 최대값을 설정해주세요. 기본값은 2.5MB입니다.
FILE_UPLOAD_MAX_MEMORY_SIZE = '2621440'
 
MEDIA_ROOT: 실제 파일이 저자될 경로입니다. 해당 경로를 생성하셔야 합니다.
MEDIA_URL: 웹 URL을 통해 첨부파일에 접근할 수 있는 URL 경로입니다.

 

common.py 작성하기

import datetime
import os
import uuid


def file_upload_path(instance, filename):
    ext = filename.split('.')[-1]
    d = datetime.datetiem.now()
    filepath = d.strftime("%Y/%m/%d")
    suffix = d.strftime("%Y%m%d%H%M%S")
    filename = "%s_%s.%s" % (uuid.uuid4().hex, suffix, ext)
    return os.path.join(filepath, filename)
 
common.py 는 제가 임시로 만든 파일로 공통 함수를 작성하기 위해 만든 파일입니다. 
file_upload_path() 함수는 파일이 업로드 될 때 파일을 올린 날짜별로 폴더로 나누어 구성하려고 만든 함수입니다.

 

models.py 작성하기

from django.db import models


class FileTest(models.Model):
    id = models.AutoField(primary_key=True)
    path = models.FileField(upload_to=file_upload_path, null=True)
 

파일을 올리기 위해서는 FileField 또는 ImageField 를 사용해야 하며 upload_to 는 파일을 올릴기 위한 경로를 표현해 주는 것입니다.

여기서 헷갈리지 말아야 하는게 settings.py 에 작성했던 MEDIA_ROOT 는 파일 경로가 시작되는 것을 말하며 파일이 최종으로 올라가는 위치는 upload_to 에 작성된 위치입니다.

즉, 최종 경로는 '/home/attachment/2016/10/18/' 의 경로에 파일이 올라가는 것입니다.

 

serializers.py 작성하기

from rest_framework import serializers
from .models import FileTest


class FileTestSerializer(serializers.ModelSerializer):
    path = serializes.FileField(required=False)

    class Meta:
        model = FileTest
        fields = '__all__'
        read_only_fields = ('id',)
 

 

views.py 작성하기

from rest_framework.viewsets import ModelViewSet

from .models import FileTest
from .serializers import FileTestSerializer


class FileTestViewSet(ModelViewSet):
    queryset = FileTest.objects.all()
    serializer_class = FileTestSerializer

    def create(self, request, *args, **kwargs):
        return super(FileTestViewSet, self).create(request, *args, **kwargs)
 

 

urls.py 작성하기

from django.conf.urls import include, url
from django.contrib import admin
from rest_framework.routers import DefaultRouter

from .views import FileTestViewSet

router = DefaultRouter()
router.register(r'file', FileTestViewSet)

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^', include(router.urls)),
]
 

admin 사이트를 사용하지 않으실 거라면 url 을 추가하지 않으셔도 됩니다.

 

sqlite3 에 table migrate 하기

$ ./manage.py migrations firstsite
$ ./manage.py migrate
 

 

File Upload 테스트하기

파일 업로드 테스트는 postman을 사용합니다.

파일 업로드 확인

경로에서 확인

$ cd /home/attachment
$ cd 2016/10/19
$ ls
b39de50460b74cb6b71b4cce1e7a767e_20161019021146.jpg
 

자신이 설정한 경로로 가서 보면 파일이 업로드된 것을 볼 수 있습니다.

 

sqlite3 에서 확인

$ sqlite3 db.sqlite3
sqlite> select * from firstsite_filetest
4|2016/10/19/b39de50460b74cb6b71b4cce1e7a767e_20161019021146.jpg​
API 응답 결과로 확인
 

API 응답 결과로 온 path 로 접속하면 /media/ 경로를 설정해 주지 않았기 때문에 404 에러가 발생합니다. 

 

/media 경로 설정하기

Django project 에서 설정하기

Django project 의 urls.py 에 설정하여 static 파일에 접근 가능하도록 만들 수 있습니다. (하지만, Django 프로젝트는 애플리케이션을 만드는데 최적화 되어있는 프레임워크입니다. 따라서 경로를 설정하는 기능은 Django project 를 사용하는 것보다는 nginx 에서 설정하는 것이 바람직합니다.)

 

from django.conf.urls import include, url
from django.contrib import admin
from django.conf.urls.static import static  # 추가
from django.conf import settings  # 추가
from rest_framework.routers import DefaultRouter

from .views import FileTestViewSet

router = DefaultRouter()
router.register(r'file', FileTestViewSet)

urlpatterns = [
                  url(r'^admin/', include(admin.site.urls)),
                  url(r'^', include(router.urls)),
              ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)  # 추가​

 

nginx 에서 설정하기

firstsite 프로젝트의 nginx 파일을 엽니다. (나는 /etc/nginx/sites-available/ 경로에 파일이 있습니다.)
$ cd /etc/nginx/sites-available
$ sudo vi firstsite
 
server
{
    listen
    8080;
    server_name
    IP_주소;

    location = / favicon.ico
    {
        access_log
        off;
        log_not_found
        off;
    }
    location / static
    / {
    root / home / parallels / firstsite;
}

location / {
    include
    uwsgi_params;
uwsgi_pass
unix: / home /
parallels / firstsite / firstsite.sock;
}

# 추가
location / media
{
    alias / home / attachment;
}

 

locaion /media 에 alias 를 MEDIA_ROOT 에 설정했던 경로와 동일하게 설정해 주면 됩니다.

nginx 서비스를 테스트 해본 후, 성공이 되면 서비스를 다시 실행시켜 줍니다.

$ sudo service nginx configtest
$ sudo service nginx restart
 

 

🙋🏻‍♂️ 후기

금일 포스팅까지 하여 Django에서의 static파일 다루기는 마무리하겠습니다. 직접 따라해보시면, 장고와 웹에 대한 이해도가 많이 상승하실거라고 믿어 의심치 않습니다. 앞으로도 열심히 공부하며 포스팅할 예정이니 많은 방문 부탁드립니다.🙇

반응형