[수정 일시]

 

먼저 질문 및 답변이 수정된 날짜를 확인할수있는 modify_date 속성을 추가하자.

projects\mysite\pybo\models.py 를 수정하자.

 

null=True 는 데이터베이스에서 modify_date 칼럼에서 null을 허용한다는 의미이며, blank=True 는 form.is_valid()를 통한 입력 데이터 검증시 값이 없어도 된다는 의미이다. 즉, 아직 modify_date 값이 없다 = 아직 수정을 하지 않았을 경우 값을 비워둘 수 있다는것을 의미한다. 모델이 변경되었으므로 makemigrations, migrate 명령을 수행하자.

 

[질문 수정]

 

먼저 질문 수정 버튼을 만들어주자.

projects\mysite\templates\pybo\question_detail.html 를 수정하자.

해석하면 수정 버튼은 로그인한 사용자와 글쓴이가 동일한 경우에만 노출되도록 {% if request.user == question.author %} 을 적용했다. 그 아래는 버튼을 구성한 것이다. 그리고 {% url 'pybo:question_modify' question.id %} URL이 추가되었으므로 pybo/urls.py 에 URL 매핑규칙을 추가해야한다.

projects\mysite\pybo\urls.py 를 수정하자.

 보면 알겠지만 views.question_modify 함수를 참조한다고 적어놨다. 아직 우리는 저 함수가 없기 때문에 새로 만들어주자,

projects\mysite\pybo\views.py 에 추가하자.

question_modify 함수는 로그인한 사용자(request.user)와 수정하려는 질문의 글쓴이(question.author)가 다르면 '수정권한이 없습니다' 오류를 발생한다. 이 오류를 발생시키기 위해 messages 모듈을 이용했다. messages 는 장고가 제공하는 모듈로 넌필드 오류를 발생시킬때 사용한다.

'수정' 버튼을 클릭하면 http://localhost:8000/pybo/question/modify/2/ 페이지가 GET 방식으로 호출되어 질문수정 화면이 보여진다. 질문 수정화면에서 사용한 템플릿은 질문 등록시 사용했던 pybo/question_form.html 파일과 동일하다. 질문 수정화면에서 저장하기 버튼을 클릭하면 http://localhost:8000/pybo/question/modify/2/ 페이지가 POST 방식으로 호출되어 데이터가 수정된다. form 태그에 action 속성이 없는 경우 디폴트 action 은 현재 페이지가 되기 때문이다.

GET 요청인 경우 질문수정 화면에 조회된 질문의 제목과 내용이반영될 수 있도록  form = QuestionForm(instance=question) 을 추가했다. 폼 생성시 이처럼 instance 값을 지정하면 폼의 속성 값이 instance 값으로 채워진다. 따라서 질문을 수정하는 화면에서 제목과 내용이 채워진 채로 보일 것이다.

POST 요청인 경우 수정된 내용을 반영해야 하는 케이스 이므로 form = QuestionForm(request.POST, instance=question) 을 추가해주었다. 이 코드의 의미는 instance 를 기준으로 QuestionForm 을 생성하지만 request.POST 의 값으로 덮어쓰라는 의미이다. 따라서 질문 수정화면에서 제목 또는 내용을 변경하여 POST 로 요청하면 변경된 내용이 QuestionForm 에 저장된다. 

질문 수정일시는 question.modify_date = timezone.now() 로 현재일시를 저장한다.

 

길게 적혀있어 어렵지만 내가 이해한 바로 설명해보자면, 질문 수정버튼을 누르면 GET 방식으로 된다는 것을 의미하고. GET 방식으로 요청된 경우에는 질문수정 화면이 나오는데 이 때 양식은 질문생성할때의 question_form.html 과 동일하고, 안의 내용들은 수정하려던 질문의 제목 과 내용이 자동으로 채워져있다. 이 상태에서 내용이나 제목을 수정해 수정하기 버튼을 누르는 것은 POST 방식으로 요청한다는 것같다. POST 방식으로 요청한 경우 수정한 내용들로 원래 있던 내용과 제목에 덮어쓰라는 것을 의미한다. 그리고 수정했기 때문에 값이 비어있던 수정일시도 현재시간으로 추가해 저장한다. 이러한 의미인것같다.

 

messages 모듈에 의해 발생되는 '수정권한이 없습니다' 오류가 표시될 수 있도록 질문 상세 화면 위쪽에 오류 영역을 추가해야한다.

projects\mysite\templates\pybo\question_detail.html 을 수정하자.

수정은 로그인 한 사용자와 글 작성자가 동일한 경우에만 가능하기 때문에 오류는 표시되지 않지만. 비 정상적인 방법으로 질문을 수정할 경우에 이 오류를 보여주어야 한다.

테스트해보자.

로그인 사용자와 작성자가 같을경우 수정 버튼이 보이고, 아닐경우 보이지 않는다. 수정 버튼을 눌렀을 경우에도 잘 작동되는지 확인해보자. 잘 작동되지만 아직은 수정일시가 표시되지는 않는다.

 

[질문 삭제]

 

질문삭제 버튼을 추가하기위해

projects\mysite\templates\pybo\question_detail.html 을 수정하자.

data-url 이 아니고 data-uri 이다. 스펠링을 잘 확인해보자.

삭제버튼은 수정버튼과 달리 href 속성 값을 javascript:void(0) 으로 설정했다. href 속성값을 이렇게 설정하면 해당 링크를 클릭해도 아무런 동작도 하지 않는다. 그리고 삭제를 실행할 URL을 얻기 위해 data-url 속성을 추가하고, 삭제 버튼이 눌리는 이벤트를 확인할 수 있도록 class 속성에 'delete' 항목을 추가했다. data-uri 속성은 자바스크립트에서 클릭 이벤트 발생시 this.dataset.uri와 같이 사용하여 그 값을 얻을 수 있다. href 에 삭제 URL을 직접 사용하지 않고 이러한 방식을 사용하는 이유는 삭제 버튼을 클릭했을때 '정말 삭제 하시겠습니까?' 같은확인창이 필요하기 때문이다.

삭제 버튼을 눌렀을 때 확인창을 나오게 하기 위해서는 다음과 같은 자바스크립트가 필요하다. 일단 눈으로만 보며 뜻을 알아보자.

<script type = 'text/javascript'>
const delete_elements = document.getElementsByClassName("delete");
Array.form(delete_elements).forEach(function(element)
{
    element.addEventListener('click', function() {
        if(confirm("정말로 삭제하시겠습니까?")){
            location.href = this.dataset.uri;
        };
    });
});
</script>

이 자바스크립트의 의미는 delete 라는 클래스를 포함하는 컴포넌트(버튼이나 링크) 를 클릭하면 "정말로 삭제하시겠습니까?" 라는 질문을 하고 "확인" 버튼을 선택했을때 해당 컴포넌트의 data-uri 값으로 URL 호출을 하라는 의미이다. "확인" 대신 "취소"를 선택하며 아무런 일도 발생하지 않는다. 이와 같은 스크립트를 추가하면 "삭제" 버튼을 클릭하고 "확인" 버튼을 선택하면 data-uri 속성에 해당하는 {% url 'pybo:question_delete' question.id %} 이 호출된다. 

자바스크립트는 HTML 구조에서 </body> 태그 바로 위에 삽입하는 것을 추천한다. 왜냐하면 이렇게 해야 화면 렌더링이 완료된 후에 자바스크립트가 실행되기 때문이다. 화면 렌더링이 완료되지 않은 상태에서 자바스크립트를 실행하면 화면의 값을 읽지 못하는 오류가 발생할수도 있고 화면 로딩이 지연되는 문제가 발생할 수 도 있다. 

projects\mysite\templates\base.html 을 다음과 같이 수정하자.

 

base.html 을 상속하는 템플릿들에서 content 블록을 구성했던것 처럼 script 를 구현한다.</body> 태그 바로 위에 {% block script %}, {% endblock %} 블록을 추가했다. 이렇게하면 base.html 을 상속하는 템플릿은 자바스크림트의 삽입위치를 신경쓸 필요없이 저 블록을 사용해 자바스크립트를 작성하면 된다.

이를 이용해

projects\mysite\templates\pybo\question_detail.html 을 다음과 같이 수정하자.

그리고 data-uri 에 {% url 'pybo:question_delete' question.id %} URL이 추가되었으므로 pybo/urls.py 에 매핑규칙을 추가해야한다.

proejcts\mysite\pybo\urls.py 를 수정하자.

그리고 위에서 정의한 views.question_delete 함수도 작성해야한다.

projects\mysite\pybo\views.py 를 다음과 같이 수정하자.

로그인이 필요하므로 @login_required 에너테이션을 적용한다. 로그인한 사용자와 글쓴이가 같을 경우에만 삭제할수 있다.

테스트 해보자

잘 작동하는지도 테스트해보자.

'Django > 따라하는 장고' 카테고리의 다른 글

24. views.py 분리  (0) 2022.11.21
23. 답변 수정 및 삭제  (0) 2022.11.19
21. author 표시  (0) 2022.11.17
20. author 속성  (0) 2022.11.16
19. 회원가입  (0) 2022.11.10

앞서 추가한 author 속성을 이용해 질문목록 에서 author 를 볼수있게 하자.

projects\mysite\templates\pybo\question_list.html

<th>글쓴이</th>로 항목을 추가하고 th 엘리먼트를 가운데 정렬하도록 tr 엘리먼트에 text-center 클래스를 추가하고, 제목의 너비가 전체의 50%가 되도록 style="width:50%" 를 지정했다. <td>{{ question.author.username }}</td> 를 추가해 질문의 글쓴이를 표시했다. 테이블 내용을 가운데 정렬하도록 tr 엘리먼트에 text-center 를 추가하고, 제목을 왼쪽 정하도록 td 엘리먼트에 text-start 클래스를 추가했다. 테이블 항목도 3개에서 글쓴이를 추가해 4개가 되었으므로 colspan 을 4로 수정했다. 테스트 해보자.

 

이제 질문상세템플릿에도 author 를 추가해 질문과 답변에 글쓴이와 작성일시가 같이 보이도록 수정하자.

projects\mysite\templates\pybo\question_detail.html 을 수정하자.

 테스트 해보자

잘 수정되었다.

'Django > 따라하는 장고' 카테고리의 다른 글

23. 답변 수정 및 삭제  (0) 2022.11.19
22. 질문 수정 및 삭제  (0) 2022.11.18
20. author 속성  (0) 2022.11.16
19. 회원가입  (0) 2022.11.10
18. 로그인 기능  (0) 2022.11.09

질문, 답변을 달면 누가 글을 작성했는지 알려주는 작성자 항목이 필요하다. Question, Answer 모델에 글쓴이 에 해당되는 author 속성을 추가해야한다.

먼저 질문 모델에 추가하기 위해 projects\mysite\pybo\models.py

 

author 필드는 User 모델을 ForeignKey 로 적용하여 선언했다. User 모델은 django.contrib.auth 앱이 제공하는 사용자 모델로 회원 가입시 데이터 저장에 사용했던 모델이다. on_delete=models.CASCADE 는 계정이 삭제되면 이 계정이 작성한 질문을 모두 삭제하라는 의미이다.

모델을 변경한 후에는 반드시 makemigrations 와 migrate 로 데이터베이스를 변경해 주어야한다.

python manage.py makemigrations 명령어를 실행하자.

명령어를 입력하면 옵션을 선택하라는 메세지가 나온다. Question 모델에 author 를 추가하면 이미 등록되어 있던 게시물에 author 에 해당되는 값이 저장되어야하는데, author 에 어떤 값을 넣어야 하는지 모르기 때문이다. 그것에 관해 어떤 옵션을 선택하라는지 묻는것이다.

1번 옵션은 one-off default 값을 제공한다. 현재 NULL 필드(author 필드) 에 값을 제공하겠다는 의미. 2번 옵션은 실행을 취소하고 models.py 에 default 값을 추가 하겠다는 옵션이다. 우리는 1번 옵션을 선택할 것이다.

1번을 입력하면

그렇게 하면 파이썬 셸이 가동된다 기본값을 지금 입력해달라는 뜻이다. 여기서 1을 다시 입력한다.

여기서 입력한 1은 admin 계정의 id 값이다. 따라서 기존 게시물의 author 에는 admin 계정이 등록된것이다. 계정을 만들때마다 id 가 1부터 순차적으로 증가하는데 처음에 만들었던 슈퍼유저 admin 이 1 인것이다.

 

다 했다면 python manage.py migrate 로 데이터베이스에 적용하자.

 

Answer 모델에도 author 속성을 똑같이 추가하자.

그리고 저번처럼 python manage.py makemigrations 명령어로를 한후 옵션을 아까처럼 선택하자.

그 후 python manage.py migrate 명령어를 수행하자.

author 속성에 null 을 허용하려면 

author = models.ForeignKey(User, on_delete=models.CASCADE,

null=True

이렇게 하면된다. 그렇게하면 migrate 할 때 데이터베이스에 null 허용 컬럼으로 생성된다.

 

Question, Answer 모델에 author 속성이 추가되었으므로 질문과 답변 저장시에 author도 함께 저장해야 한다.

projects\mysite\pybo\views.py 파일을 다음과 같이 수정하자. 

답변과 질문의 글쓴이는 현재 로그인한 계정이므로 answer.author = request.user 로 처리했다. request.user 는 현재 로그인한 계정의 User 모델 객체이다. 이제 다시 서버를 시작하고 테스트 하면 잘 된다.

하지만 로그아웃 상태에서 질문 또는 답변을 등록하면 다음과 같은 ValueError가 발생한다.

이 오류는 request.user 가 User 객체가 아닌 AnonymousUser 객체라서 발생한 것이다. 로그인 상태일땐 User 로그아웃일땐 AnonymousUser 이다. 앞에서 author 속성을 정의할 때 User를 이용하도록 했는데 로그아웃시에는 author 에 User 가 아닌 AnonymousUser 가 대입되어 오류가 발생한 것이다.

이를 해결하기 위해선 request.user 를 사용하는 함수에 @login_required 애너테이션을 사용해야 한다. 이 애너테이션이 붙은 함수는 로그인이 필요한 함수를 의미한다.

projects\mysite\pybo\views.py 를 다음과 같이 수정하자.

질문생성과 답변생성함수는 함수내에서 request.user 를 사용하므로 로그인이 필요한 함수이기 때문에 위에 @login_required 어노테이션을 사용했다. 로그아웃상태에서 실행을 하려고 하면 로그인 화면으로 이동한다.

실제로 로그아웃상태에서 질문등록하기를 누르면 로그인 화면으로 이동이 된다. 이 때의 URL 을 확인해보자.

URL을 확인해보면 next 파라미터가 있는데 이는 로그인 성공후 next 파라미터에 있는 URL로 페이지를 이동하겠다는 의미이다. 하지만 실제로 해보면 로그인을 하면 원래 하려던 질문 등록페이지로 안가고 홈페이지로 가진다. 이를 해결하려면 로그인 템플릿에 hidden 타입의 next 항목을 추가해야한다.

projects\mysite\templates\common\login.html 을 다음과 같이 수정하자.

이렇게 하면 로그인 후 next 항목의 URL 로 이동한다.

 

로그아웃시에 질문 작성하기버튼을 눌렀을때의 오류는 해결했지만 로그아웃상태일때 답변을 달려고 할 때 가 있다. 로그아웃 상태에서도 저장하기 버튼을 누르면 로그인 화면으로 자동으로 넘어가지만 문제는 작성해놓은게 사라진다는 점이다. 작성하기 버튼을 눌렀을때 로그인 화면으로 이동하게 하는것보다 아예 로그아웃상태이라면 작성을 못하게 하는게 좋다.

projects\mysite\templates\pybo\question_detail.html 파일을 다음과 같이 수정하자.

의미를 해석하자면 로그인 상태가 아닌 경우 textates 태그에 disabled 속성을 적용하여 입력을 못하게 만들었다. 보면 알겠지만 {% if not user.is_authenticated %} 태그는 현재 사용자가 로그아웃 상태인지를 체크하는 태그이다.

로그아웃상태일때는 답변내용이 사진과 같이 사용하지 못하게 막혀있다. 이 상태에서 답변등록 버튼을 누르면 로그인 화면으로 이동한다. 그리고 로그인을 하면 오류가 발생할것이다. 로그인시 전달된 next 파라미터 때문에 로그인 후에 답변등록 URL 인 /answer/create 가 GET 방식으로 호출되기 때문이다. 하지만 답변등록시 POST 방식이 아닌경우 HttpResponseNotAllowed 오류가 발생하도록 코딩했다 그래서 오류가 발생하는것이다. 이를 해결하기위해

 projects\mysite\pybo\views.py 파일을 다음과 같이 수정하자.

from django.http import HttpResponseNotAllowed 를 삭제하고. else 부분에 form = AnswerForm() 를 추가하자.

이제 로그아웃상태에서 답변등록 버튼을 누른후 로그인을 하면 원래 화면으로 잘 돌아간다.

'Django > 따라하는 장고' 카테고리의 다른 글

22. 질문 수정 및 삭제  (0) 2022.11.18
21. author 표시  (0) 2022.11.17
19. 회원가입  (0) 2022.11.10
18. 로그인 기능  (0) 2022.11.09
17. 템플릿 필터 및 답변 개수 표시  (0) 2022.11.07

로그인 기능을 구현했으니 이제 회원가입 기능을 구현해보자.

projects\mysite\templates\navbar.html 파일을 다음과 같이 수정하자.

 

로그인/로그아웃 링크 바로 옆에 회원가입 링크를 추가했다. 회원가입은 로그아웃 상태에서만 보일수있게 했다. {% url 'common:signup' %} 태그를 적어넣었으므로 URL매핑규칙을 추가해줘야 한다. projects\mysite\common\urls.py 에 다음과 같이 추가하자.

회원가입 링크를 누르면 views.signup 함수가 실행된다. 이제 이 함수를 만들어 줘야하지만 그 전에 일단 계정생성시 사용할 UserForm을 projects\mysite\common\forms.py 파일을 추가해 새로작성하자.

UserForm 은 djnago.contrib.auth.forms 모듈의 UserCreationForm 클래스를 상속하여 만들었다. 그리고 email 속성을 추가했다. UserForm 을 따로 만들지 않고 UserCreationForm 을 그대로 사용해도 되지만 위처럼 이메일 등의 속성을 추가하기 위해서는 UserCreationForm 클래스를 상속해서 만들어야 한다. password2 는 password1 을 제대로 입력했는지 대조하기 위한 값이다. 

 

이제 아까 만들어야했던 views.signup 함수를 작성하자. projects\mysite\common\views.py 파일에 다음과 같이 작성하자.

signup 함수는 POST 요청인 경우에는 화면에서 입력한 데이터로 사용자를 생성하고 GET 요청인 경우에는 회원가입 화면을 보여준다. form.cleaned_data.get 함수는 폼의 입력값을 개별적으로 얻고 싶은 경우에 사용하는 함수로 여기서는 인증시 사용할 사용자명과 비밀번호를 얻기 위해 사용한다. 사용자를 생성한 후에 자동 로그인 될 수 있도록 authenticated, login 함수가 사용되었다. authenticated 와 login 함수는 django.contrib.auth 모듈의 함수로 사용자 인증과 로그인을 담당한다.

 

이제 회원가입 화면을 구성하는 common/signup.html 템플릿을 작성해야한다.

projects\mysite\templates\common\signup.html 파일을 추가하고 다음과 같이 작성하자.

form 태그 밑에는 오류를 표시하기위해 form_errors.html 템플릿을 include 했다.

 

이제 테스트를 해보자.

비밀번호와 비밀번호 확인이 다를 경우 오류가 발생한다. 일단 id 는 stdiohan 비밀번호는 testpasswd 로 설정했다. 그리고 

http://localhost:8000/admin/ 페이지를 요청해보면

이런 경고 메세지가 나온다. 어드민 페이지는 슈퍼유저로 접속해야한다. 저번에 만든 아이디 admin 비밀번호 1111 로 로그인해 보면

이런 화면이 나온다 여기서 사용자(들) 버튼을 누르면

아까 만든 계정을 확인할 수 있다.

'Django > 따라하는 장고' 카테고리의 다른 글

21. author 표시  (0) 2022.11.17
20. author 속성  (0) 2022.11.16
18. 로그인 기능  (0) 2022.11.09
17. 템플릿 필터 및 답변 개수 표시  (0) 2022.11.07
16. Paginator  (0) 2022.11.05

로그인 기능을 만들어보자. 로그인, 로그아웃을 도와주는 앱은 django.contrib.auth 이다. 이 앱은 장고 프로젝트 생성시 자동으로 추가된다. projects\mysite\config\settings.py 를 확인해보자.

 

로그인, 로그아웃기능을 구현해야한다. 로그인, 로그아웃기능은 pybo앱에 구현할수도 있지만, 하나의 웹 사이트에는 파이보와 같은 게시판 서비스 이외에도 블로그나 쇼핑몰같은 굵직한 단위의 앱들이 함께 있을 수 있기 때문에 공통으로 사용되는 기능인 로그인기능은 하나의 앱에 종속시키는게 좋다. 그렇기 때문에 common 앱에 구현하는게 좋다.

 

일단 common 앱을 다음 명령어를 입력해 새로 생성하자.

그렇게 하면 

자동으로 디렉토리와 파일들이 자동으로 생성된다.

그리고 config\settings.py 파일에 방금 생성된 common 앱을 등록하면된다.

projects\mysite\config\settings.py 에 다음과 같이 추가하자.

common 앱의 urls.py 파일을 사용하기 위해 projects\mysite\config\urls.py 파일을 다음과 같이 수정하자.

이렇게 하면 http://localhost:8000/common/ 으로 시작하는 URL 은 모두 common/urls.py 파일을 참조한다. 참조하기 위해 파일을 새로 만들자.

파일은 원하는 방법으로 알아서 만들자.

아직 common 앱에 어떤 기능도 구현하지 않았으므로 urlpatterns 는 빈상태로 놔두면 된다.

 

[로그인]

 

먼저 로그인 화면으로 진입할 수 있도록 projects\mysite\templates\navbar.html 파일의 로그인 링크를 다음처럼 수정하자.

navbar.html 파일에서 템플릿 태그로 {% url 'common:login' %} 를 작성했으므로 common/urls.py 파일에 URL 매핑규칙을 추가해야한다.

projects\mysite\common\urls.py 를 다음과 같이 수정하자.

로그인 뷰는 따로 만들 필요없이 위 코드처럼 django.contrib.auth 앱의 LoginView 를 사용하도록 설정했다.

 

여기까지 하고 파이보 페이지에서 로그인 버튼을 눌러보면 오류 페이지가 나타난다.

이 오류는 registration 디렉토리에 login.html 파일이 없다는 것을 의미한다. 앞에서 사용한 LoginView는 registration 이라는 템플릿 디렉토리에서 login.html 파일을 찾는다. 이 파일을 찾지 못해 오류가 발생한것이다. 해결하려면 registration/login.html 템플릿파일을 작성해야한다.

그런데 우리는 로그인을 common 앱에 구현할 것이므로 오류메세지에 표시한 것처럼 registraion 디렉토리에 템플릿 파일을 생성하기보다는 common 디렉토리에 템플릿을 생성하는게 좋다. 이를위해 LoginView 가 common 디렉토리의 템플릿을 참조할 수 있도록 projects\mysite\common\urls.py 파일을 다음과 같이 수정하자.

이렇게 수정하면 registrration 디렉토리가 아니라 common 디렉토리에서 login.html 파일을 참조하게 된다. 그 후 다시 로그인 버튼을 누르면

오류 내용이 수정된것을 볼 수 있다. 오류 내용을 보면 알 수 있듯이 이젠 common/login.html 이 없다는 오류다.

그렇다면 common/login.html 파일을 생성하기 위해 common 템플릿 디렉토리를 다음과 같이 생성하자. 그 후 login.html 파일을 만들자. projects\mysite\templates\common\login.html 에 다음과 같이 작성하자.

사용자ID 와 비밀번호를 입력으로 받아 로그인하는 간단한 템플릿이다. 로그인에 사용되는 사용자 ID를 의미하는 username 과 비밀번호를 의미하는 passwrod 항목이 있다. 이 2가지는 django.contrib.auth 인증시 username 과 password 이 2개의 항목은 반드시 필요하다.

그리고 {% csrf_token %} 바로 밑에 Include 태그로 포함된 form_errors.html 템플릿  파일은 다음과 같이 작성해주자.

projects\mysite\templates\form_errors.html 파일을 새로 만들고 작성하자.

form_errors.html 템플릿은 로그인 실패시 로그인이 왜 실패했는지 알려주는 역할을 한다. 폼 오류에는 다음과 같이 두 가지 종류의 오류가 있다. 필드 오류(field.errors) 와 넌필드오류(form.non_field_errors) 이다.

필드 오류는 사용자가 입력한 필드 값에 대한 오류로 값이 누락되었거나 필드의 형식이 일치하지 않는 경우에 발생하는 오류이다. 넌필드 오류는 필드의 값과는 상관없이 다른 이유로 발생하는 오류이다. form_errors.html 템플릿은 필드 오류와 넌필드 오류 모두를 표시하기 위해 삽입되는 템플릿이다. question_form.html, question_detail.html 템플릿에서 오류를 표시하기위해 추가했었던 HTML 코드를 {% include "form_errors.html" %} 로 대체해도 좋다.

 

이제 로그인 버튼을 눌러 로그인을 해보자.

아무것도 입력하지 않고 로그인 버튼을 누르면 사용자 이름과 비밀번호가 필수 항목이라고 나온다. 현재 로그인이 가능한 사용자는 초반에 만들었던 슈퍼유저 admin 하나밖에없다. 그때 만들었던 슈퍼유저를 사용해 id 에 admin 비밀번호에 1111을 입력해 로그인을 하자.

로그인에 성공하면 오류가 나온다. 오류메세지를 보면 알수있듯이 로그인에 성공해 http://localhost:8000/accounts/profile/ 로 가야하는데 아직 해당 페이지가 구성되어있지 않기 때문이다. 하지만 /accounts/profile/ 은 내가 파이보에 구성한 URL 구조와 맞지 않으므로 로그인 성공시 / 페이지로 이동할 수 있도록 projects\mysite\config\settings.py 를 다음과 같이 수정하자.

마지막 줄에 추가하면 된다.

이렇게 수정해도 다음과 같은 오류가 발생한다.

이번에는 수정해서 로그인에 성공하면 http://localhost:8000/ 페이지로 가야하지만 아직 해당페이지에 대한 URL 매핑 규칙을 작성하지 않았다. 이를 추가하기 위해 projects\mysite\config\urls.py 에 다음과 같이 수정하자.

이제 / 페이지 요청에 대해 path('', views.index, name='index') 가 작동하여 pybo/views.py 파일의 index 함수가 실행된다.

이제 로그인에 성공하면 정상적으로 작동한다. 하지만 로그인을 했음에도 로그인 버튼이 로그아웃버튼으로 바뀌지 않고 여전히 로그인 버튼으로 남아있다. 이를 해결하기위해 proejcts\mysite\templates\navbar.html 을 다음과 같이 수정하자.

{% if user.is_authenticated %} 은 현재 사용자가 로그인 되어있는지를 판별한다. 로그인되어있는지를 판별하고 로그인 되어있으면 '로그아웃' 링크를 표시하고 아니면 '로그인' 링크를 표시한다. 로그인 상태에서는 로그아웃 링크에 사용자명을 의미하는 {{ user.username }} 도 추가로 표시한다.

로그아웃 링크가 추가되었으므로 {% url 'common:logout' %}에 대응하는 URL 매핑을 추가해야한다. projects\mysite\common\urls.py 파일을 다음과 같이 수정하자.

이제 잘 되어있는지 확인해보자.

잘 적용되어있다. 로그아웃 시 이동할 위치도 projects\mysite\config\settings.py 파일에 추가하자.

그리고 이제 로그아웃을 다시 해보면 / 페이지로 이동한다.

'Django > 따라하는 장고' 카테고리의 다른 글

20. author 속성  (0) 2022.11.16
19. 회원가입  (0) 2022.11.10
17. 템플릿 필터 및 답변 개수 표시  (0) 2022.11.07
16. Paginator  (0) 2022.11.05
15. 네비게이션 바  (0) 2022.11.04

+ Recent posts