위와 같이 상품 리스트에 등록된 제품들의 상세 리뷰를 전체 조회할 수 있는 페이지와 해당 리뷰를 클릭하면 상세한 리뷰 내용을 볼 수 있는 화면을 구성하는 가이드를 작성한다.
Flask를 사용하고, firebase의 realtime database 이용한다. GoormIDE에 Flask 컨테이너를 만들어 데이터 베이스를 연동하고, 상품을 등록하는 코드까지 구현한 뒤 이 화면 구성이 가능하다.
아래의 코드를 참조하여 원하는 스타일로 리뷰 조회 화면을 구현할 수 있다.
<!-- 핵심 코드 -->
<table>
<tr>
{% for key, value in row1 %}
<td> 제목: {{value.title}} <br>
<img src="static/images/{{ value.img_path }}" width="240" height="200" onclick="location.href='/view_review_detail/{{ key }}/';" style="cursor:pointer;">
</td>
{% endfor %}
</tr>
<!-- 원하는 사진 배열을 고려하여 코드 작성 -->
</table>
전체 리뷰 조회 화면에서 사진을 몇 개의 열로 보이게 할 것인지 정하고 그에 맞춰서 row 수를 다르게 해 코드를 작성하면 된다.
위의 코드를 분석해보면 먼저 <table>의 형식으로 표현하고 싶기 때문에 이 컨테이너를 사용한다. {% for key, value in row1 %}은 row1이라는 컬렉션을 순회한다. 이 컬렉션은 백엔드 서버에서 템플릿으로 전달된다. 이때 각 반복에서 key, value 값을 제공하는데 key는 식별자, value는 항목의 세부사항을 포함한다. {{value.title}}은 현재 반복에서 항목 제목을 출력한다. 아래 코드는 img_path의 속성을 사용하여 이미지 파일의 경로를 동적으로 설정한다.
<!-- 핵심 코드 -->
<p> review title is <b> {{data.title}} </b> and rate is {{data.rate}} points out of 5 points. </p>
<p> {{data.review}} </p>
<img src="../../static/images/{{data.img_path}}"
전체 리뷰 조회 화면에서 한 개의 리뷰를 선택했을 때 어떤 화면이 보이게 할지 결정하는 코드이다.
{{data.title}}은 템플릿 변수로 서버로부터 전달된 data 객체의 title 속성 값을 동적으로 표시한다. {{data.rate}}는 리뷰의 평점을 동적으로 보여준다. 마찬가지로 {{data.review}}는 서버에서 전달된 data 객체의 review 속성 값을 표시한다. 이미지를 웹 페이지에 표시하기 위해서 소스 경로를 지정해야한다. data.img_path에 저장된 값으로 동적으로 설정된다.
#핵심 코드
@application.route("/review")
def view_review():
data = DB.get_reviews()
item_counts = lent(data)
tot_count = len(data)
for i in range(row_count):
if(i == row_count -1) and (tot_count % per_row != 0):
locals()['data_{}].format(i)] = dict(list(data.items())[i*per_row:])
else:
locals()['data_{}].format(i)] = dict(list(data.items())[i*per_row:(i+1)*per_row])
return render_template(
"review.html",
datas = data.items(),
row1 = locals()['data_0'].items(),
row2 = locals()['data_1'].items(),
)
@application.route("/view_review_detail/<name>/")
def view_review_detail(name):
review_data = DB.get_review_byname(name)
if review_data:
return render_template("review_detail.html", data=review_data)
else:
return render redirect(url_for('view_review'))
URL 경로 “/review”에 대한 요청을 view_review 함수로 라우팅하는 @application.route(”/review”)로 함수를 시작한다. 함수를 def로 정의한 다음, data = DB.get_reviews()로 데이터베이스로부터 리뷰 데이터를 가져온다. for 루프를 사용하여 데이터를 페이지에 맞게 여러 행으로 나눈다. 그리고 나누어진 행에 동적 변수명을 사용하여 각 행의 데이터를 저장한다. render_template으로 Flask의 템플릿 렌더링 함수를 호출한다. 이 함수에서는 사용할 HTML 템플릿 파일, 템플릿에 사용될 데이터를 포함한다.
마찬가지로 URL 경로”/view_review_detail/<name>/”에 대한 요청을 view_review_detail 함수로 라우팅한다. <name>은 경로 변수로 URL에 전달되는 리뷰의 이름이다. def로 함수를 정의하여 name 값을 인자로 받도록 설정한다. review_data = DB.get_review_byname(name)으로 데이터베이스에서 name에 해당하는 리뷰 데이터를 가져온다. if문으로 만약 리뷰 데이터가 존재하면 템플릿을 렌더링하여 review_data를 템플릿에 전달한다. 이것이 사용자에게 리뷰 상세 정보를 보여주는데 사용된다. 만약 리뷰 데이터가 존재하지 않으면 리뷰 페이지로 리디렉트한다.
def get_review_byname(self, name):
reviews = self.db.child("review").get().val()
for key, value in reviews.items():
if key == name:
return value
def get_reviews(self):
reviews = self.db.child("review".get().val()
return reviews
데이터베이스에서 리뷰 데이터를 검색하고 반환하는데 사용된다. get_review_byname 함수는 특정 리뷰의 이름에 해당하는 데이터를 데이터베이스에서 검색한다. reviews = self.db.child(”review”).get().val()은 데이터베이스에서 review 노드의 모든 리뷰 데이터를 가져온다. for key, 는 가져온 리뷰 데이터를 반복하여 각 리뷰의 식별자인 키와 리뷰 데이터를 확인한다. 만약 현재 리뷰의 키가 함수에 전달 된 name과 일치하면 해당 리뷰의 값을 반환한다.