고객의 네 번째 기능 구현-2
영화 예매하기 기능을 이어서 구현하겠다.
2. screening_date_id 입력받기
2-1. movie_id를 제대로 입력했다면 해당 movie_id를 가진 영화의 screening_date_id, screening_date를 출력하고 이 값을 screening_date_id를 입력 받는 함수에 넘겨준다 (입력받은 값이 존재하는 값인지 확인하기 위함).
<오류1,2>
[오류1] 로 구현했더니 [오류2]가 되었다.
<해결>
Not Found 오류의 원인은 redirect와 url_for 사용법에 문제가 있기 때문이다.
url_for()은 함수 이름을 기반으로 URL을 생성한다.
따라서 url_for()에 정의한 라우트 경로가 아닌, 함수 이름을 지정해야 한다.
<오류3>
form 태그의 action 경로는 라우트의 URL 경로와 일치해야 한다.
따라서 오류3 처럼 수정했다.
<오류4,5>
SQLite에서는 %s 플레이스홀더를 사용하지 않고, ? 플레이스홀더를 사용해야 한다.
따라서 [오류4], [오류5]으로 수정했다.
<오류6>
유효하지 않은 영화 ID를 입력하니 오류가 떴다.
유효하지 않은 영화 ID를 입력했을 때 redirect(url_for('book_movie') 을 했는데 인자로 name과 member_id를 넘겨주지 않았더니 생긴 오류였다.
[오류6]처럼 수정했더니 오류메세지 출력하려고 만든 message는 출력되지 않았지만 오류 페이지(BuildError)는 뜨지 않았다. (검색창이 리셋됨)
이제 유효하지 않은 movie ID 입력 시 오류 message를 띄우도록 flash()와 get_flashed_messages()를 사용해 routes.py를 수정하겠다.
@app.route("/movies/book/<name>/<int:member_id>", methods=['GET', 'POST'])
def book_movie(name, member_id):
result1 = print_movie()
message = ""
if request.method == "POST":
movie_id = request.form['movie_id']
if not movie_id:
flash("Movie ID is required! Please enter a valid ID.")
return redirect(url_for('book_movie', name=name, member_id=member_id))
else:
try:
movie_id = int(movie_id)
if valid_movie_id(movie_id, result1):
# 유효한 경우, 다음 페이지로 이동
return redirect(url_for('select_screening_date_id', name=name, member_id=member_id, movie_id=movie_id))
else:
flash("Invalid movie ID. Please enter a valid movie ID.")
return redirect(url_for('book_movie', name=name, member_id=member_id))
except ValueError:
flash("Invalid input. Please enter a valid integer for movie ID.")
return redirect(url_for('book_movie', name=name, member_id=member_id))
return render_template('user/book_movie_4.html', name=name, member_id=member_id, movies=result1, message=message)
@app.route("/movies/book/screening_date_id/<name>/<int:member_id>/<int:movie_id>")
def select_screening_date_id(name, member_id, movie_id):
result2 = print_screening_schedule(movie_id)
movie_title = get_movie_title(movie_id)
return render_template('user/screening_date_id_4.html', movie_title=movie_title, result=result2)
Flash 메시지를 팝업으로 띄우기 (book_movie_4.html 일부)
models.py
def get_movie_title(movie_id):
con = get_db_connection()
cursor = con.cursor()
cursor.execute("select movie_title from movie where movie_id = ?", (movie_id,))
result = cursor.fetchone()
con.close()
return result
def print_screening_schedule(movie_id):
con = get_db_connection()
cursor = con.cursor()
cursor.execute("select distinct screening_date_id, screening_date from screeningschedule s where s.movie_id = ?",
(movie_id,))
result = cursor.fetchall()
con.close()
return result
2-2. 출력된 상영 일정을 보고 예매할 영화의 정보를 클릭한다. 그리고 선택된 정보의 screening_date_id를 저장한다.
[상영일정] 에서 원하는 일정에 해당하는 네모 칸을 클릭하면 screening_date_id 를 routes.py로 받아오도록 html 파일을 수정하겠다.
- <a> 태그: HTML의 하이퍼링크를 생성하는 태그
- href 속성: 클릭 시 이동할 URL을 지정
[1] 처럼 url 을 지정하면 가독성과 유지보수성 측면에서 최선은 아니다. 인자가 많아지면 URL이 복잡해지고, 보안 및 코드 관리가 어려워질 수 있다.
따라서 쿼리 파라미터를 사용하는 방식 (?key=value)을 활용하겠다.
[2], [3] 처럼 수정하니 url도 간단해졌고 각 인자들도 잘 받아와서 [4]처럼 출력되었다.
<결과화면>
이렇게 유효하지 않은 영화 ID를 입력하면 오류메세지가 뜨고 다시 입력할 수 있도록 페이지가 리셋된다.