html로 구현된 화면에서 이미지를 업로드하면
django를 통해 지정된 폴더에 이미지가 저장되고
저장된 주소는 MySQL에도 저장되도록 제작했습니다.
설명을 이해하기 쉽도록 변수는 한글로 기재하지만
실제 프로그래밍 시에는 영어로 된 변수를 설정해주셔야 합니다.
참고한 사이트
진행 전, 가상환경에는 Pillow가 설치되어 있어야 합니다.
터미널에서 pip install Pillow를 실행하여 설치할 수 있습니다.
장고와 MySQL의 기본 빌드는 이미 구성된 상태임을 전제로 합니다.
참고 사이트에서는 Core라는 앱을 하나 생성해서 사용했지만
저는 기능별로 앱을 구분해서 사용했습니다.
따라서 아래 두 개의 앱을 구분해서 보셔도 되고
한 앱에서 모든 기능을 구현하시는 분들은
앱1과 앱2를 동일하게 보시면 됩니다!
models.py가 선언된 앱 = 앱이름1
데이터를 읽고 쓸 앱 = 앱이름2
라고 하겠습니다.
settings.py 의 맨 밑에 있는 MEDIA_URL과 MEDIA_ROOT를 수정해줍니다.
import os
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
1. MEDIA_URL : 미디어 파일의 url을 설정
2. MEDIA_ROOT : 미디어 파일의 저장 경로를 정의
이미지 파일이 저장된 경로를 저장할 MySQL 테이블을 만들어 주겠습니다.
저는 설명이 이해되기 쉽도록 한글 이름으로 적었지만 아래 한글 변수들은 모두 프로그래밍 시 영문으로 작성해주셔야 합니다.
앱이름/models.py
from django.db import models
class 테이블(models.Model) :
컬럼_파일위치 = models.FileField(upload_to='Uploaded Files/%y/%m/%d/', blank=True)
컬럼_업로드날짜 = models.DateField(auto_now = True)
파일 저장 위치는 '프로젝트 폴더/media/년/월/일' 로 하겠습니다.
(%/y/%m/%d 가 year, month, date를 의미해요)
파일이 많으면 프로그램이 찾는 데 오래걸리지만
이렇게 하위 폴더를 여러번 생성해서 파일을 저장하면
사용 시 효율적입니다.
이렇게 선언해주고 터미널에서
python manage.py makemigrations
python manage.py migrate
를 실행하면
이런 테이블이 생성됩니다.
여기서 id는 자동으로 생성되고, 데이터가 추가될때마다 하나씩 증가하는 int 예요.
이제 사람들이 파일을 업로드 할 수 있도록 html 화면 구성을 해줍니다.
저는 아래와 같은 모양으로 만들거예요
그렇지만 CSS 요소는 다 빼고 꼭 필요한 부분만 추려서 코드 설명할게요!
html 위치는 "프로젝트폴더/앱이름2/templates" 입니다.
이 html은 이제 폼.html 이라고 할게요
<div>
데이터를 업로드하세요! <br>
<form action="{% url '앱이름2 : '이름_파일업로드' %} " method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="인풋_파일업로드">
<input type="submit" value="등록하기">
</form>
</div>
1. form action : 폼이 제출(submit)되면 이동할 url을 의미합니다.
아직까지 {% url '앱이름2 : 펑션_파일업로드 %}는 이제 작성할 views에서의 function입니다.
2. method="POST" : 폼의 전송 방식은 POST와 GET 두 가지가 있는데, 여기서는 파일을 보내기 위해 POST를 사용합니다.
3. {% csrf_token %} : 폼을 POST로 보내기 위해 필수적으로 필요한 보안 요소예요. 폼 중 아무곳에나 위치해도 상관없어요.
4. <input type="file"> : 파일선택하는 버튼과 선택된 파일 이름이 보이는 부분입니다.
5. <input type="submit"> 폼을 제출하는 버튼이에요. <button> 과는 약간 달라요.
그리고 폼을 제출하고 나서 등록되어있는 사진이 모두 뜰 페이지도 만들어줄게요.
결과.html이라고 하겠습니다~
<table>
<tr>
<th>ID</th>
<th>File Path</th>
<th>Upload Date & Time</th>
</tr>
{% for 변수_222 in 키_테이블의모든정보 %}
<tr>
<td>{{ 변수_222.id }}</td>
<td>{{ 변수_222.컬럼_파일위치 }}</td>
<td>{{ 변수_222.컬럼_업로드날 }}</td>
</tr>
{% endfor %}
</table>
이제 폼이 제출되면 수행할 동작을 지정해 줄 거예요.
"프로젝트폴더/앱이름2/views.py"로 이동합니다.
폼이 실행되면 현재 url에 폼의 입력 값들이 파라미터로 달라붙을거예요.
from 앱이름1 import models
from django.shortcuts import render
from 앱이름.models import 테이블
def 펑션_파일업로드(request):
if request.method == "POST":
#폼에서 데이터를 받아와 변수화시키기
변수_업로드파일 = request.FILES["인풋_파일업로드"]
# 정보를 파일에 저장하기
변수_파일저장 = models.테이블(
컬럼_파일위치 = 변수_업로드파일
)
변수_파일저장.save()
변수_테이블의모든정보 = models.테이블.objects.all()
return render(request, "앱이름2/결과.html", context = {
"키_테이블의모든정보": 변수_테이블의모든정보
})
이제 url 과 views에서 방금 선언해준 '펑션_파일업로드'를 연결해줘야 해요
앱이름2/urls.py
from 앱이름2 import views
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
app_name = "앱이름2"
urlpatterns = [
path("", views.펑션_파일업로드, name = "이름_파일업로드"),
]
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL,
document_root = settings.MEDIA_ROOT
)
이제 드디어 아까 폼을 제출하면 연결되는 url에 선언한 내용이 다 나왔네요.
{% url '앱이름2 : '이름_파일업로드' %} 는 '앱이름2'의 urls.py 파일에 선언된 많은 path중에 'name = 이름_파일업로드'인것을 찾아가도록 선언 해 준거랍니다.
이제 터미널에 python manage.py runserver을 한 뒤 테스트해보시면 됩니다!
그런데 저는.. 화면에서 '모든 업로드 된 이미지들'이 아니라 제가 방금 올린 이미지만 확인하고싶어요.
코드를 약간 수정해주겠습니다.
일단
1. 파일을 업로드하면 방금 업로드 한 파일의 컬럼 정보만 불러와야 합니다.
object.all() 로 테이블의 모든 정보를 가져오면 안되는거죠.
2. 그래서 필터링을 하기 위해 MySQL에 파일 업로드 위치를 넣어줄 때, 이 위치를 변수화해서 url에 넣어줄거예요.
3. 넣어준 url을 처리할 두번째 function을 선언해주면
4. 'url을 통해 변수화되어 넘어온 파일 업로드 위치' = 'MySQL 테이블의 컬럼_파일위치' 인 컬럼만
걸러 화면에 표시해 줄 수 있겠죠?
앱이름2.views 를 수정해주겠습니다.
import도 추가되었으니 빠트린 것 없이 모두 기재했는지 반드시 확인하세요!
from django.shortcuts import render, get_object_or_404
from 앱이름1 import models
from 앱이름1.models import 테이블
from django.http import HttpResponseRedirect
from django.urls import reverse
def 펑션_파일업로드(request):
if request.method == "POST":
#폼에서 데이터를 받아와 변수화시키기
변수_업로드파일 = request.FILES["인풋_파일업로드"]
# 정보를 파일에 저장하기
변수_파일저장용 = models.테이블(
변수_파일업로드 = 인풋_파일업로드
)
변수_업로드파일.save()
변수_파일업로드위치=변수_파일저장용.컬럼_파일위치
변수_해당컬럼 = get_object_or_404(테이블, 컬럼_파일위치 = 변수_파일업로드위치)
변수_해당컬럼_id = 변수_해당컬럼.id
return HttpResponseRedirect(reverse('앱이름2:펑션_화면표시', args=(변수_해당컬럼_id,)))
def 펑션_화면표시(request, 변수_해당컬럼_id):
변수_해당컬럼 = get_object_or_404(테이블, id= 변수_해당컬럼_id)
context = {'키_해당컬럼': 변수_해당컬럼}
return render(request, '결과.html', context)
urls 수정, 리다이렉트 된 path를 추가해줍니다. url에 int타입 id를 같이 보내줬으니까 인식하도록 해줘야해요.
from 앱이름2 import views
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
app_name = "앱이름2"
urlpatterns = [
path("", views.펑션_파일업로드, name = "이름_파일업로드"),
path("<int: 변수_해당컬럼_id >/", views.펑션_화면표시, name='펑션_화면표시')
]
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL,
document_root = settings.MEDIA_ROOT
)
폼을 제출하면 이동하는 html화면도 수정해서 해당되는 사진만 뜨도록 바꿔줍니다.
<div>
<img src= "/media/{{키_해당컬럼.uploadedFile}}" />
{{oiai.uploadedFile}}
</div>
완성~!!!
아래 접힌 페이지를 확인하시면 모든 완성된 코드와 파일 경로가 기재되어 있습니다.
'Python > Django' 카테고리의 다른 글
[django] form 입력값을 sql에 저장하기 (0) | 2022.05.09 |
---|---|
[django] 장고에서 return 지정하기 (1) | 2022.05.04 |
Django -MySQL 데이터에 필터 걸어 딕트로 가져오기 (0) | 2022.04.15 |
Django -url정리하기 (0) | 2022.04.13 |
장고(django)-이미지 파일 올리고 관리 (0) | 2022.04.11 |
댓글