Django 에서 파일(이미지)를 업로드하기 위해서는 FileField 또는 ImageField 를 사용하면 된다.
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 테스트하기
파일 업로드 테스트는 Chrome app 인 postman 을 사용한다.
파일 업로드 확인
경로에서 확인
$ cd /home/attachment
$ cd 2016/10/19
$ ls
a596b9ac49ba43419187ae3cb605fb4e_20161019010704.jpg
자신이 설정한 경로로 가서 보면 파일이 업로드된 것을 볼 수 있다.
sqlite3 에서 확인
$ sqlite3 db.sqlite3
sqlite> select * from firstsite_filetest
2|2016/10/19/a596b9ac49ba43419187ae3cb605fb4e_20161019010704.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
'Python > Django' 카테고리의 다른 글
[Django] django-crontab (0) | 2016.10.28 |
---|---|
[Django] values() values_list() flat (0) | 2016.10.26 |
[Django] uwsgi + nginx in ubuntu (0) | 2016.10.18 |
[Django] Test (0) | 2016.10.12 |
[Django] Extra (0) | 2016.10.06 |
댓글