기억에 남는 인생 영화에 대한 정보와 평가를 저장하고 조회할 수 있는 서비스입니다.
- 데이터를 생성,조회,수정,삭제할 수 있는 Webapplication제작
- Djangoweb framework를 사용한 데이터 처리
- DjangoModel과 ORM에 대한 이해
- 관리자 페이지를 통한 데이터 관리
📦04_pjt
┣ 📂movies
┃ ┣ 📂migrations
┃ ┃ ┣ 📜0001_initial.py
┃ ┃ ┗ 📜__init__.py
┃ ┣ 📂templates
┃ ┃ ┗ 📂movies
┃ ┃ ┃ ┣ 📜detail.html
┃ ┃ ┃ ┣ 📜edit.html
┃ ┃ ┃ ┣ 📜index.html
┃ ┃ ┃ ┣ 📜new.html
┃ ┃ ┃ ┗ 📜search.html
┃ ┣ 📜admin.py
┃ ┣ 📜apps.py
┃ ┣ 📜models.py
┃ ┣ 📜tests.py
┃ ┣ 📜urls.py
┃ ┣ 📜views.py
┃ ┗ 📜__init__.py
┣ 📂mypjt
┃ ┣ 📜asgi.py
┃ ┣ 📜settings.py
┃ ┣ 📜urls.py
┃ ┣ 📜wsgi.py
┃ ┗ 📜__init__.py
┣ 📂templates
┃ ┗ 📜base.html
┣ 📜.gitignore
┣ 📜db.sqlite3
┣ 📜manage.py
┣ 📜README.md
┗ 📜requirements.txt
필드명 | 데이터 타입 | 역할 |
---|---|---|
title | varchar(20) | 영화 제목 |
audience | integer | 관객 수 |
release_date | date | 개봉일 |
genre | varchar(30) | 장르 |
score | float | 평점 |
poster_url | text | 포스터 경로 |
trailer_url | text | 예고편 경로 |
description | text | 줄거리 |
review | text | 후기 |
MOVIDIC
의index
페이지입니다.
서비스를 소개하는header
영역과, 등록한 영화 정보를 확인할 수 있는section
영역으로 이루어져 있습니다.
영화 카드를 클릭하면, 해당 영화의 상세 페이지로 이동됩니다.
views.index
페이지가 요청되면, 등록된 영화 전체 데이터들을QuerySet
으로 반환하여 페이지를 렌더링합니다.def index(request): movies = Movie.objects.all() context = { 'movies': movies, } return render(request, 'movies/index.html', context)
영화 정보를 등록할 수 있는
new
페이지 입니다.
Navigation bar
의new
를 통해 접근 가능합니다.
Sumbmit
버튼으로 제출하면 등록한 영화의 상세 페이지로 이동됩니다.
new.form
POST
방식으로 입력된 데이터들을 서버로 전송합니다.
CSRF
공격을 방지하기 위한CSRF_Token
이 들어있습니다.<form class="row g-3" action="{% url 'movies:create' %}" method="POST"> {% csrf_token %} <div class="col-md-4"> <label for="title" class="form-label font-monospace">TITlE</label> <input type="text" class="form-control" name="title" id="title" required> </div> ... <div class="col-12"> <button class="btn btn-primary font-monospace" type="submit">Submit</button> <a href="{% url 'movies:index' %}" class="btn btn-secondary" role="button">Back</a> </div> </form>
views.create
Submit
으로 제출된 데이터들을DB
에 저장합니다.
저장 후 해당 영화의 상세 페이지로 리다이렉트합니다.def create(request): movie = Movie() movie.title = request.POST.get('title') movie.audience = request.POST.get('audience') ... movie.save() return redirect('movies:detail', movie.pk)
등록된 영화의 상세 내용을 조회하는
detail
페이지입니다.
해당 영화 데이터를 삭제나 수정을 할 수 있는 버튼이 함께 있습니다.
-
views.detail
요청과 함께 넘겨 받은pk
로 영화를 특정하여, 해당 데이터들로 페이지를 렌더링합니다.def detail(request, pk): movie = Movie.objects.get(pk=pk) context = { 'movie': movie, } return render(request, 'movies/detail.html', context)
등록된 영화의 상세 내용을 수정할 수 있는
edit
페이지입니다.
-
edit.form
new.form
과 같은 방식으로 데이터 전송과CSRF
공격을 대비합니다.
Reset
버튼을 통해 수정 전 초기 상태로 되돌릴 수 있습니다.<form class="row g-3" action="{% url 'movies:update' movie.pk%}" method="POST"> {% csrf_token %} <div class="col-md-4"> <label for="title" class="form-label font-monospace">TITlE</label> <input type="text" class="form-control" name="title" id="title" value="{{movie.title}}"required> </div> ... <div class="col-12"> <input class="btn btn-success font-monospace" type="reset" value="Reset"> <button class="btn btn-primary font-monospace" type="submit">Submit</button> <a href="{% url 'movies:detail' movie.pk%}" class="btn btn-secondary" role="button">Back</a> </div> </form>
-
views.detail
과views.create
와 같은 방식으로, 영화를 특정하고 영화 정보 데이터를 저장합니다.
특정 영화 정보를 삭제하기 위한
url
입니다.
-
views.delete
detail
페이지에서 삭제 요청을 통해 함께 받아온 데이터의pk
로 해당 영화 정보를 삭제합니다.def delete(request, pk): movie = Movie.objects.get(pk=pk) movie.delete() return redirect('movies:index')
Navigation bar
를 통해 영화 제목을 키워드로 검색하면,
해당 키워드와 매칭이 되는 영화들이 조회되는search
페이지입니다.
-
nav.form
Navgiation bar
에서form
으로 영화 제목을 입력 받아 서버로 전송합니다.<nav class="navbar navbar-light navbar-expand-md bg-light fixed-top"> <div class="container-fluid font-monospace"> ... <form class="d-flex" role="search" action="{% url 'movies:search' %}" method="GET"> <input class="form-control me-2" type="search" name="title" placeholder="Movie Title" aria-label="Search"> <button class="btn btn-outline-success" type="submit">Search</button> </form> </div> </nav>
-
views.search
search/
url
로 함께 들어온title
파라미터로 특정한 영화들의QuerySet
을 반환하여 페이지에 렌더링합니다.def search(request): movies = Movie.objects.filter(title__contains=request.GET.get('title')) context = { 'movies': movies, } return render(request, 'movies/search.html', context)
- 결국엔
index
페이지에서처럼, 영화 데이터들을QuerySet
으로 반환시켜 페이지를 렌더링시키면 되는 부분이었습니다. - 다만 다른 점은,
filter
메소드를 통해 원하는 영화 정보들만QuerySet
에 담아 반환시켜야 한다는 점입니다! - 필터링에 사용할 키워드는 간단히
Navigaiton bar
의search form
을GET
방식으로 입력을 받으면 됩니다.
첫
Django
프로젝트로CRUD
기능을 구현했습니다.
Django
는 처음이지만 다른 프레임워크는 경험이 있었기 때문에,
두리뭉실하게 잡혀 있던CRUD
의 전체적인 흐름을 다시 한번 되짚고 실습할 수 있었던 좋은 경험이었습니다.
또한HTML
,CSS
,Boostrap
을 활용하여 페이지도 간단히 꾸며보았습니다.
배운지 불과 한달 밖에 안되었고, 당시엔 손에 익었던 부분들이었는데도 가물가물한 부분이 꽤 많았습니다.
확실히 프로그래밍은 익힐 習의 영역을 무시할 수 없다는 걸 다시 한번 자각할 수 있었습니다.
배운 기술들을 잊어 버리면 아까우니, 앞으로도 기회가 생길 때마다 종합적으로 활용해 보려고 합니다!