구현할 때 어려웠던 기능
- 나중에 메인화면에 문제집 제목의 리스트를 쭉 불러오는 것으로 했기 때문에 콜렉션에서 문제집하나의 고유의 값인 id값으로 문제집 콜렉션의 데이터를 가져와야한다고 판단했다. (다른 방법도 있지 않을까!) id 값을 콜렉션에서 가져올때 계속 type에러가 났다. 오브젝트 아이디와 관련된 타입 에러였는데 기술매니저님께 여쭤보고 4번째 줄로 str값을 oid로 바꾼거고 그것을 또다시 str으로 바꿔주는 작업이 필요했다는 것을 배웠다. (파이썬 파일의 4번째줄의 작업) 그리고 서버 쪽에서 render template하고 html에서 jinja2 문법으로 값을 넣을 부분을 지정해주는 방법을 알려주셨다.
@app.route("/questions/<id>", methods=["GET"])
def find_one_question(id):
question = db.toy.find_one({"_id": bson.ObjectId(oid=str(id))})
question['_id'] = str(question['_id'])
return render_template('seoa.html', question=question)
<div class="question">
<div class="q_num">1.</div>
<div class="q_content"> {{ question.question_name }} </div>
</div>
<div class="opt_container">
<div class="option">
<input class="radio" type="radio" id="1-1" name="one" value="1" onclick="answer_check(value)">
<label for="1-1">① {{ question.question1 }}</label>
</div>
- db에서 정답인 번호를 가져와서 라디오 버튼에서 체크된 값과 비교하여 alert로 정답 여부 확인하는 기능 구현할때. 체크한 값을 db collection에 저장하고 다른 collection에서 저장되어있던 정답을 동시에 get 해야하는거라 생각해서 get과 post를 동시에 수행할 수 있는 api를 어떻게 만들지 고민이 있었다.
이후 시간 관계상 결과지를 만들지 않아도 돼서 db에 저장하지는 않아도 됐다(스택오버플로우에서 ajax로 radio button값을 저장하는 방법은 찾았으나 사용할일은 없었다ㅎ). 스크립트 api url 부분 링크에 오브젝트 아이디를 가져오는 것은 위에서 배운 jinja 문법과 유사했다. 기술매니저님께 여쭤보니 꼭 db에 값을 저장하지 않더라도 radio버튼에서 value값을 get 함수의 parameter로 불러와서 비교를 하는 방법을 알려주셨다!
@app.route("/questions/<id>/check", methods=["GET"])
def get_answer (id):
question = db.toy.find_one({"_id": bson.ObjectId(oid=str(id))})
question['_id'] = str(question['_id'])
print(question)
answer_list = question['correctNum']
return jsonify({'answer': answer_list})
function answer_check(value) {
$.ajax({
type: "GET",
url: "/questions/{{ question._id }}/check",
data: {},
success: function(response) {
let correctNum = response['answer'];
if (correctNum == value) {
alert("정답입니다🥳")
} else {
alert("오답입니다🥹")
}
}
});
}
- 마지막으로 어려웠던 기능은 메인화면에 저장된 문제집의 제목 값의 하이퍼링크를 쌓는 것이었다. 어떻게 문제집의 id값(전체)와 제목 전체를 가져와야할지에 대한 고민이 있었다. 매니저님께서 방법은 파이썬 파일에서 데이터를 가공하는 방식과 스크립트에서 가공하는 방식 두가지가 있다고 힌트를 주셨다. 파이썬 파일로 가공을 해서 jinja2 for문으로 구현할 수 있었다.
@app.route('/')
def home():
all_toy = list(db.toy.find({}))
all_toy_ids = []
all_toy_ids2 = []
for value in all_toy:
all_toy_ids.append(str(value['_id']))
for value2 in all_toy:
all_toy_ids2.append(value2['question_name'])
print(all_toy_ids)
print(all_toy_ids2)
return render_template('index.html', all_toy_ids=all_toy_ids, all_toy_ids2=all_toy_ids2, zip=zip)
<div class="link_box" id="link_box">
<p class="link">○문제지의 해당란에 성명과 수험번호를 정확히 쓰시오.</p>
<p class="link">○수험번호는 ex)20230208 의 8자릿 수로 기입하시오.</p>
<p class="link">○답안지의 필적 확인란에 다음의 문구를 정자로 기입하시오.</p>
{% for ml, ml2 in zip(all_toy_ids2, all_toy_ids) %}
<div><a href="/questions/{{ ml2 }}"> {{ ml }} </a></div>
{% endfor %}
</div>
느낀 점
- 5시간동안 object id 타입에러로 씨름할때 같은 조 팀장님이 오류를 잡으면서도 계속 궁금해하고 탐구하려는 자세에서 정말 배울 점이 많았다.
- jinja2 문법은 처음 배우게 되었는데 알아두면 꽤 활용도가 높았다. 검색해봤을때 꽤 예전 자료들이 나와서 요즘은 많이 쓰이지 않는 것 같았다.
- 웹종반 강의 자료는 보면 여러번 보면 볼 수록 구석구석 몰랐던 것들이 더 많이 보이는 것 같다.
- 첫 프로젝트부터 많이 어려운 도전이었지만 공부하는 자세면에서나 기술적인 면에서나 얻어가는 것이 많은 프로젝트였다.
- 아.. 깃은 참 어렵다...!