[Django] 파일 업로드 테스트 with Nginx, uWSGI
🚀 들어가며...
- 저번 포스팅에서 장고에서의 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'
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)
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 응답 결과로 온 path 로 접속하면 /media/ 경로를 설정해 주지 않았기 때문에 404 에러가 발생합니다.
/media 경로 설정하기
Django project 에서 설정하기
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 에서 설정하기
$ 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파일 다루기는 마무리하겠습니다. 직접 따라해보시면, 장고와 웹에 대한 이해도가 많이 상승하실거라고 믿어 의심치 않습니다. 앞으로도 열심히 공부하며 포스팅할 예정이니 많은 방문 부탁드립니다.🙇