사용자에게 보여지는 부분 / 웹 페이지의 골격 = HTML 로 작성된 부분
Template Tag
HTML 이 파이썬 코드 ( 장고 프로젝트 ) 로부터 데이터를 바로 넘겨받아 손쉽게 처리할 수 있는 도구
{} 로 감싸는 형태 , 파이썬 기본 구문에 사용 가능
ex ) for문 , if문
템플릿과 모델 사이를 이어주는 다리 역할
STEP 1 프론트엔드가 백엔드에게 데이터 요청
STEP 2 백엔드에서 데이터를 뽑아옴
STEP 3 데이터 처리 후 프론트엔드에게 제공
routing 역할 + 서버로의 해당 주소에 할당된 리소스를 요청하는 역할
Model > Templates > View > URL 순서로 작업할 예정
STEP 1 photo / templates / photo folder 생성
STEP 2 photo_list.html file 생성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Photo App</title>
</head>
<body>
<h2>사진 목록 페이지</h2>
<h3><a href="{% url 'photo_post' %}">New Photo</a> </h3>
<section>
{% for photo in photos %} # photos 사진 여러 장 가져오기 / photo 변수로 하나씩 불러오기
<div>
<h2>
<a href="{% url 'photo_detail' pk=photo.pk %}">{{photo.title}}</a>
</h2>
<img src="{{photo.image}}" width="50%">
<p>{{photo.author}}</p> # photo.author 불러오기
<p>{{photo.description}}</p> # photo.description 불러오기
</div>
{% endfor %}
</section>
</body>
</html>
from django.shortcuts import render
from .models import Photo # 현재 폴더 내 models 에 있는 Photo class 호출
def photo_list(request):
photos = Photo.objects.all() # photo.objects.all() : Photo 모델 데이터 모두 가져와 {} 에 넣어 템플릿으로 전달하기
return render (request , 'photo/photo_list.html', {'photos':photos}) # photo/photo_list.html rendering
from django.urls import path
from . import views
urlpatterns = [
path('', views.photo_list, name ='photo_list'),
]
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('photo.urls')),
] # '' : 루트 주소 , photo/urls.py 등록 > project urls.py
New Photo 링크 연결하여 새로운 사진 등록하는 것은 뒤쪽에서 다룰 것
STEP 1 photo_detail.html file 생성
STEP 2 view 작성 photo/views.py
def photo_detail(request, pk):
photo = get_object_or_404(Photo, pk = pk)
return render (request, 'photo/photo_detail.html', {'photo': photo})
path('photo/<int:pk>/',views.photo_detail, name ='photo_detail'),
{% for photo in photos %}
<div>
<h2>
<a href="{% url 'photo_detail' pk=photo.pk %}">{{photo.title}}</a>
# photo_detail url 연결 , pk : 데이터 구분하는 변수 > 사진 구분
</h2>
<img src="{{photo.image}}" width="50%">
<p>{{photo.author}}</p>
<p>{{photo.description}}</p>
</div>
첫 번째 사진 클릭했을 때 , 상단바 확인 photo/1/ 세부 정보 변경됨을 알 수 있음
Form
사용자가 데이터를 입력해 서버로 보내도록 도와주는 양식
사용자 = 양식을 채우고 POST 방식으로 요청을 보냄
서버 = 해당 요청을 받아 처리함
Form tag 데이터 전송 방법
GET
입력한 데이터를 URL에 붙여 전송 , 데이터 전부 노출되서 보안에 취약 , 전송 속도 FAST , 페이지 이동시 파라미터 전송
ex ) 검색 결과 등 간단하고 보안이 필요하지 않은 경우
POST
입력한 데이터를 본문 안에 포함해서 전송 , 입력한 데이터가 URL 에 보이지 않아 GET 방식보다 보안에 우수
form 으로 데이터를 전송할 때 해당 토큰이 같이 전달될 수 있도록 숨김 데이터로 같이 전송해주도록 해야함
ex ) 로그인 , 회원가입 등 보안이 필요하거나 복잡한 형태의 데이터를 전송할 경우
csrf_token (Cross - Site Request Forgery )
폼에 숨어있는 악의적인 코드 , 사용자가 원하지 않는 글을 작성하는 보안 취약점을 방지하기 위한 보안 토큰
서버에서 랜덤한 값을 생성하여 reponse 에 포함하여 전달 , 사용자 세션 정보와 연관되어 서버에 전송하고 서버는 토큰과 세션의 유효성을 검사해 요청 처리
STEP 1 photo_post.html file 생성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Photo App</title>
</head>
<body>
<h1><a href="/">홈으로 돌아가기</a> </h1>
<div>
<section>
<h2>New Photo</h2>
<form method ="POST"> # POST 방식으로 요청 전송
{% csrf_token %} {{form.as_p}} # csrf 공격 방지
<button type = "submit">완료 !</button>
</form>
</section>
</div>
</body>
</html>
STEP 3 form 작성
from django import forms
from .models import Photo
class PhotoForm(forms.ModelForm): # field 값을 입력으로 받는 form PhotoForm class 생성
class Meta:
model = Photo
fields = ('title','author','image','description')
from django.shortcuts import render, redirect
from .models import Photo
from .forms import PhotoForm
get_object_or_404,
def photo_post(request):
if request.method == "POST":
form = PhotoForm(request.POST)
if form.is_valid():
photo = form.save(commit=False)
photo.save()
return redirect('photo_detail', pk=photo.pk)
else:
form = PhotoForm()
return render(request,'photo/photo_post.html',{'form':form})
path('photo/new/',views.photo_post, name='photo_post'),
<h2>사진 목록 페이지</h2>
<h3><a href="{% url 'photo_post' %}">New Photo</a> </h3>
STEP 1 templates 사용
작성 기능과 templates SAME , 새로 작성할 필요 X
def photo_edit(request, pk):
photo = get_object_or_404(Photo, pk=pk) # pk : 수정할 대상 찾아오기
if request.method == "POST":
form = PhotoForm(request.POST, instance=photo) # instance = photo : 수정 대상이 될 데이터 선정
if form.is_valid():
photo = form.save(commit=False)
photo.save()
return redirect('photo_detail', pk=photo.pk)
else: # GET 요청 > photo 데이터를 form에 담기 > photo_detail.html 에 넘기기 ( 기존 데이터를 수정 )
form = PhotoForm(instance=photo)
return render(request, 'photo/photo_post.html', {'form':form})
path('photo/<int:pk>/edit/', views.photo_edit, name='photo_edit'),
<h3><a href="{% url 'photo_edit' pk=photo.pk %}">Edit Photo</a></h3>
Django 의 MTV pattern 을 바탕으로 기능 구현 실습하며 스터디 진행