카테고리 없음

고객의 네 번째 기능 구현-2

dmswo 2025. 1. 10. 18:42

영화 예매하기 기능을 이어서 구현하겠다.

 

2. screening_date_id 입력받기

 

2-1.  movie_id를 제대로 입력했다면 해당 movie_id를 가진 영화의 screening_date_id, screening_date를 출력하고 이 값을 screening_date_id를 입력 받는 함수에 넘겨준다 (입력받은 값이 존재하는 값인지 확인하기 위함).

 

<오류1,2>

[오류1] 로 구현했더니 [오류2]가 되었다.  

오류1
오류2

<해결>

Not Found 오류의 원인은 redirect와 url_for 사용법에 문제가 있기 때문이다.

url_for()은 함수 이름을 기반으로 URL을 생성한다.

따라서 url_for()에 정의한 라우트 경로가 아닌, 함수 이름을 지정해야 한다.

 

<오류3>

form 태그의 action 경로는 라우트의 URL 경로와 일치해야 한다. 

따라서 오류3 처럼 수정했다.

오류3

<오류4,5>

SQLite에서는 %s 플레이스홀더를 사용하지 않고, ? 플레이스홀더를 사용해야 한다.

따라서 [오류4], [오류5]으로 수정했다.

오류4
오류5

<오류6>

유효하지 않은 영화 ID를 입력하니 오류가 떴다. 

유효하지 않은 영화 ID를 입력했을 때  redirect(url_for('book_movie') 을 했는데 인자로 name과 member_id를 넘겨주지 않았더니 생긴 오류였다. 

[오류6]처럼 수정했더니 오류메세지 출력하려고 만든 message는 출력되지 않았지만 오류 페이지(BuildError)는 뜨지 않았다. (검색창이 리셋됨)

오류6

 

이제 유효하지 않은 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

 

[1] 처럼 url 을 지정하면 가독성과 유지보수성 측면에서 최선은 아니다. 인자가 많아지면 URL이 복잡해지고, 보안 및 코드 관리가 어려워질 수 있다.

따라서 쿼리 파라미터를 사용하는 방식 (?key=value)을 활용하겠다. 

[2], [3] 처럼 수정하니 url도 간단해졌고 각 인자들도 잘 받아와서 [4]처럼 출력되었다.

2
3

 

4

 

 

<결과화면>

영화 ID로 1 입력

 

이렇게 유효하지 않은 영화 ID를 입력하면 오류메세지가 뜨고 다시 입력할 수 있도록 페이지가 리셋된다.