본문 바로가기
Research/Django

[Django] 점프 투 장고 튜토리얼 - 3-13 앵커

by RIEM 2021. 11. 25.

Django 점프 투 장고 정리

작성일 : 2021-11-25

문서버전 : 1.0 

개요

이 문서는 점프 투 장고 사이트의 장고 튜토리얼 학습 내용을 정리한 내용입니다.

레퍼런스

점프 투 장고 https://wikidocs.net/72242

3-13 앵커

지금까지 많은 기능을 추가했다. 더 나아가기 전에 몇 가지 문제점을 해결하고 넘어가자.

 

발견된 문제점은 답글 작성, 수정 후 화면이 리다이렉트되며 페이지 상단으로 스크롤이 자동으로 이동된다. 이때 본인이 작성한 답변을 확인하기 위해 다시 스크롤을 내려야 한다는 불편함이 발생한다. 

 

이를 해결하기 위해 Ajax와 같은 비동기 통신 기술을 사용할 수도 있지만 더 쉬운 방법인 앵커(anchor) 태그를 이용해보자.

 

앵커(anchor)태그는 HTML에서 URL 호출 시 원하는 위치로 이동시킨다. HTML 중간에 <a name=”django”></a>라는 앵커 태그가 있을 경우 HTML 호출하는 URL 뒤에 #django라 붙여주면 해당 페이지가 호출될 때 해당 앵커로 스크롤이 자동 이동된다.

 

앵커 태그를 활용해서 답변등록, 답변수정, 댓글등록, 댓글수정 시 원하는 위치로 이동할 수 있도록 수정해보자.

 

답변 앵커

답변 앵커 추가

> ../mysite/templates/pybo/question_detail.html

답변 작성, 수정 시 이동해야 할 앵커 태그를 질문 상세 템플릿에 추가하자.

 

(... 생략 ...)

<h5 class="border-bottom my-3 py-2">{{question.answer_set.count}}개의 답변이 있습니다.</h5>

{% for answer in question.answer_set.all %}

<a name="answer_{{ answer.id }}"></a>

(... 생략 ...)

 

For문 이후로부터 답변이 반복되어 표시된다. 그러므로 for문 바로 <a name=”answer_{{ answer.id }}”></a> 앵커태그를 추가해주자. 앵커 태그의 name 속성은 유일한 값이 와야 하기 때문에 answer_{{ answer.id }} 와 같이 답변 id를 사용했다.

 

답변 redirect

답변 등록하거나 수정 시 위에서 지정한 앵커 태그로 이동하도록 코드를 수정해주자. 

 

아래 코드는 답변 등록 또는 답변 수정을 한 뒤 사용한 기존 코드의 일부다.

Return redirect('pybo:detail', question_id=question.id)

 

기존 코드에서 앵커 코드를 포함하면 아래와 같다.

Return redirect('{}#answer_{}'.format(resolve_url('pybo:detail', question_id=question.id), answer.id))

 

Resolve_url 함수는 Pybo:detail URL에 #answer_2와 같은 앵커 태그를 추가하기 위함이다. Resolve_url은 실제 호출되는 URL 문자열을 리턴하는 장고의 함수다. 


> ../mysite/pybo/views/answer_views.py

answer_views.py의 answer_create, answer_modify 함수도 수정해주어야 한다.

 

(... 생략 ...)

from django.shortcuts import render, get_object_or_404, redirect, resolve_url

(... 생략 ...)

 

@login_required(login_url='common:login')

def answer_create(request, question_id):

    (... 생략 ...)

            return redirect('{}#answer_{}'.format(

                resolve_url('pybo:detail', question_id=question.id), answer.id))

    (... 생략 ...)



@login_required(login_url='common:login')

def answer_modify(request, answer_id):

    (... 생략 ...)

 

    if request.method == "POST":

        form = AnswerForm(request.POST, instance=answer)

        if form.is_valid():

            (... 생략 ...)

            return redirect('{}#answer_{}'.format(

                resolve_url('pybo:detail', question_id=answer.question.id), answer.id))

    (... 생략 ...)



함수별로 Redirect 함수 사용한 곳이 두 군데 있을 수도 있는데 주의해야 한다. 오류 발생 시 실행하는 redirect 함수는 앵커 위치로 이동할 필요가 없다는 점에서 수정하지 않아도 된다.

답변 앵커 확인

수정 후 스크롤이 자동으로 수정된 위치에 앵커링 된 것을 볼 수 있다.

 

댓글 앵커

댓글 앵커 또한 답변 앵커와 동일한 방식으로 구현하면 된다.

 

댓글 앵커 추가

> ../templates/pybo/question_detail.html

(... 생략 ...)

<!-- 질문 댓글 Start -->

{% if question.comment_set.count > 0 %}

<div class="mt-3">

{% for comment in question.comment_set.all %}

    <a name="comment_{{ comment.id }}"></a>

 

(... 생략 ...)

 

<!-- 답변 댓글 Start -->

{% if answer.comment_set.count > 0 %}

<div class="mt-3">

{% for comment in answer.comment_set.all %}

    <a name="comment_{{ comment.id }}"></a>

(... 생략 ...)

 

질문, 답변 댓글에 모두 앵커 태그를 추가해주었다.\

 

댓글 redirect

> ../pybo/views/comment_views.py 수정

(... 생략 ...)

from django.shortcuts import render, get_object_or_404, redirect, resolve_url

(... 생략 ...)

 

@login_required(login_url='common:login')

def comment_create_question(request, question_id):

    (... 생략 ...)

    if request.method == "POST":

        form = CommentForm(request.POST)

        if form.is_valid():

            (... 생략 ...)

            return redirect('{}#comment_{}'.format(

                resolve_url('pybo:detail', question_id=comment.question.id), comment.id))

    (... 생략 ...)

 

@login_required(login_url='common:login')

def comment_modify_question(request, comment_id):

    (... 생략 ...)

    if request.method == "POST":

        form = CommentForm(request.POST, instance=comment)

        if form.is_valid():

            (... 생략 ...)

            return redirect('{}#comment_{}'.format(

                resolve_url('pybo:detail', question_id=comment.question.id), comment.id))

    (... 생략 ...)

 

@login_required(login_url='common:login')

def comment_create_answer(request, answer_id):

    (... 생략 ...)

    if request.method == "POST":

        form = CommentForm(request.POST)

        if form.is_valid():

            (... 생략 ...)

            return redirect('{}#comment_{}'.format(

                resolve_url('pybo:detail', question_id=comment.answer.question.id), comment.id))

    (... 생략 ...)

 

@login_required(login_url='common:login')

def comment_modify_answer(request, comment_id):

    (... 생략 ...)

    if request.method == "POST":

        form = CommentForm(request.POST, instance=comment)

        if form.is_valid():

            (... 생략 ...)

            return redirect('{}#comment_{}'.format(

                resolve_url('pybo:detail', question_id=comment.answer.question.id), comment.id))

    (... 생략 ...)

 

댓글 등록 또는 수정 시 해당 앵커로 이동하도록 redirect URL을 수정했다. 댓글 삭제일 경우 화면을 스크롤 이동시킬 필요가 없기 때문에 그대로 두었다.

 

답변을 새로 달 경우 앵커 태그가 정상적으로 잘 작동한다!

 

댓글