Django 게시판 만들기 (4) - 글 수정/삭제 하기, 로그인 구현 본문
- 글 수정하기
- detail.html에서 수정하기 버튼을 생성
더보기
<a href="{% url 'board:post_modify' post.id %}" class="btn btn-secondary" style="float:right">수정하기</a>
- 수정할 글의 고유번호인 post_id를 인자로 주고 매핑이 namespace가 board이고 url별칭이 post_modify인 것을 찾는다
더보기
path('post/modify/<int:post_id>/', views.post_modify, name='post_modify'),
- views.py에서 modify_post를 작성한다
더보기def post_modify(request, post_id): # request:<WSGIRequest: GET '/board/post/modify/3/'>, post_id:3(세번째로 작성한 글을 수정하므로) """ 글 수정하기 """ post = get_object_or_404(Post, pk=post_id) # <class 'board.models.Post'> # model에서 Post클래스의 pk가 수정하려는 post의 번호인 객체(?)를 가져온다. # post.id, post.title, post.content, post.create_date 조회시 수정하려는 글(행)에 저장된 데이터가 들어있음 if request.method == 'POST': # ↓ 저장하기 눌러야 활성화 # print(request.method) -> GET or POST 반환 form = Postform(request.POST, instance=post) # 폼들 만들되, post데이터를 사용하여 폼을 채운다. # <tr><th><label for="id_title">Title:</label></th><td><input type="text" name="title" value="두번 째 글 쓰기" maxlength="150" required id="id_title"></td></tr> <tr><th><label for="id_content">Content:</label></th><td><textarea name="content" cols="40" rows="10" required id="id_content">두번 째 글의 내용입니다</textarea></td></tr> if form.is_valid(): post = form.save(commit=False) # 커밋하지 않고 form에 있는 내용을 저장한다 post객체에 담아(?) post.modified_date = timezone.now() post.save() # db에 내용 저장 및 반영 return redirect('board:detail', post_id=post.id) # 수정한 글로 이동 else: form = Postform(instance=post) # 인스턴스 키워드로 기존에 존재하는 모델 객체를 인수로 준다. context = {'form': form} # 템플릿에 넘길 폼 객체를 dict형태로 넘긴다 return render(request, 'board/post_form.html', context)
- detail.html에서 수정하기 버튼을 생성
- 글 삭제하기
- detail.html에서 삭제하기 버튼 생성
더보기
<a href="{% url 'board:post_delete' post.id %}" class="btn btn-secondary" style="float:left">삭제하기</a>
- url 매핑 작성
더보기
path('post/delete/<int:post_id>/', views.post_delete, name='post_delete'),
- views.py에서 post_delete를 작성한다
더보기
def post_delete(request, post_id): """ 글 삭제하기 """ post = get_object_or_404(Post, pk=post_id) # post모델에서 삭제하려는 글의 id에 해당하는 레코드의 객체를 가져온다 post.delete() # 가져온 레코드를 삭제한다 return redirect('board:index')
- detail.html에서 삭제하기 버튼 생성
- 로그인 구현
- python manage.py startapp accounts : 로그인 및 인증 기능을 담당할 app accounts 새로 생성
- config/settings.py에 새로 생성한 accounts app을 등록한다
- path('accounts/', include('accounts.url')), : ~account/~ 로 시작하는 url이 요청이 들어오면 accounts앱 쪽에서 처리하도록 config.urls.py에 등록
- accounts/urls.py 파일 생성
더보기
app_name = 'accounts' urlpatterns = [ ]
- base.html의 navbar에서 로그인 href='#' 을 href={% url 'accounts:login' %} 으로 변경
- namespace: accounts, url별칭: login
- accounts의 login으로 연결되도록 매핑한다
- namespace: accounts, url별칭: login
- 탬플릿 태그로 {% url 'accounts:login' %}를 사용했으므로, accounts.urls.py에 매핑규칙을 추가한다
-
더보기
from django.urls import path from django.contrib.auth import views as auth_views # 이 부분을 추가해야 django auth에 내장되어있는 LoginView와 LogoutView를 사용할 수 있다. 따라서 accounts앱에 따로 views.py에서 loginview, logoutview 코드를 작성할 필요가X(장고에 내장된 것을 임포트하여 가져다 쓰므로) # 앱 폴더 내에 있는 views.py와 충돌하지 않도록 별칭을 설정한다. app_name = 'accounts' urlpatterns = [ path('login/', auth_views.LoginView.as_view(template_name='accounts/login.html'), app_name='login'), # django\contrib\auth\views.py에 있는 클래스 LoginView를 가져다 쓴다. # as_view() : 클래스형 뷰에서 제공하는 클래스로 진입하기 위한 진입 메소드. View 클래스에 정의되어 있음. -> 여기서는 클래스형 view인 LoginView에 진입하기 위한 메소드라는 것. 함수view vs 클래스view : if문으로 http 메소드를 구분하는 함수view와 다르게, if문없이 함수로 코드구분을 하여 깔금하게 작성할 수 있다. 아래 주소 참고. # 참고 : http://ruaa.me/django-view/ # as_view() 안에 인자는 LoginView는 regstration이라는 템플릿 디렉터리에서 login.html파일을 찾는다. 찾는 파일을 accounts디렉터리의 템플릿을 참조하도록 한 것. ]
-
- template/common 디렉터리를 생성해 login.html 파일을 생성한다.
-
더보기
{% extends "base.html" %} {% block content %} <div class="container my-3"> <form method="post" action="{% url 'accounts:login' %}"> {% csrf_token %} {% include "form_errors.html" %} <div class="mb-3"> <label for="username">사용자ID</label> <input type="text" class="form-control" name="username" id="username" value="{{ form.username.value|default_if_none:'' }}"> </div> <div class="mb-3"> <label for="password">비밀번호</label> <input type="password" class="form-control" name="password" id="password" value="{{ form.password.value|default_if_none:'' }}"> </div> <button type="submit" class="btn btn-primary">로그인</button> </form> </div> {% endblock %}
- 로그인에 사용되는 사용자ID 를 의미하는 username과 비밀번호를 의미하는 password 항목은 django.contrib.auth 앱이 요구하는 필수 항목. (필드는 여러개가 있다. username, password, first_name, email, is_staff, is_active 등, 참고 : https://docs.djangoproject.com/en/4.0/ref/contrib/auth/ )
-
- templates/form_errors.html 파일을 작성한다
-
더보기
<!-- 필드 오류와 넌필드 오류를 출력한다. --> {% if form.errors %} <div class="alert alert-danger"> {% for field in form %} <!-- 필드 오류 --> {% if field.errors %} <div> <strong>{{ field.label }}</strong> {{ field.errors }} </div> {% endif %} {% endfor %} <!-- 넌필드 오류 --> {% for error in form.non_field_errors %} <div> <strong>{{ error }}</strong> </div> {% endfor %} </div> {% endif %}
- 필드 오류(field.errors) : 사용자가 입력한 필드 값에 대한 오류로, 값이 누락되거나 필드의 형식이 일치하지 않는 경우에 발생하는 오류이다.
- 넌필드 오류(form.non_field_errors) : 필드의 값과 상관없이 다른 이유로 발생하는 오류이다.
-
- config/settings.py에 로그인 성공 후 이동하는 URL을 추가한다.
-
더보기# 로그인 성공후 이동하는 URL
LOGIN_REDIRECT_URL = '/' - 로그인이 성공하면 django.contrib.auth 패키지는 디폴트로 /accounts/profile/이라는 url로 이동시키기 때문에, /profile/ 이 없는 대신 다른 페이지로 이동하라고 설정한 것이다.
-
- board/urls.py에 '/'페이지에 대응하는 url매핑규칙을 추가한다
-
더보기
from board import views # 기존 내용에 추가 urlpatterns = [ path('', views.index, name='index'), # 추가 ]
-
- 로그아웃 구현
- 로그인을 했을 경우, 네비게이션바에 로그인이 로그아웃으로 변경되도록 base.html파일을 수정한다
-
더보기
<li class="nav-item "> {% if user.is_authenticated %} <! authetincated : 진짜임을 증명하다 > <a class="nav-link" href="{% url 'accounts:logout' %}">로그아웃</a> {% else %} <a class="nav-link" href="{% url 'accounts:login' %}">로그인</a> {% endif %} </li>
- 템플릿에서 user 사용하기
- 뷰 함수에서 템플릿에 user 객체를 전달하지 않더라도 템플릿에서는 django.contrib.auth 기능으로 인해 User객체를 사용할 수 있다. 대표적으로 다음과 같은 것들이 있다.
- user.is_authenticated : 현재 사용자가 인증되었는지 여부 (로그인한 상태라면 true, 로그아웃 상태라면 false) authenticated(진짜임을 증명하다)
- user.is_anonymous : is_authenticated의 반대경우, (로그인한 상태라면 false, 로그아웃 상태라면 true) anonymous(익명의)
- user.username : 사용자명 (사용자ID)
- user.is_superuser : 사용자가 슈퍼유저인지 여부
- 참고 : https://docs.djangoproject.com/en/4.0/ref/contrib/auth/
- 뷰 함수에서 템플릿에 user 객체를 전달하지 않더라도 템플릿에서는 django.contrib.auth 기능으로 인해 User객체를 사용할 수 있다. 대표적으로 다음과 같은 것들이 있다.
-
- accounts/urls.py에 logout url매핑도 추가한다
-
더보기
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
-
- 로그아웃 시 리다이렉트할 위치도 config/settings.py에 추가한다
-
더보기
# 로그아웃 성공후 이동하는 URL LOGOUT_REDIRECT_URL = '/'
-
- ㅇ
- 로그인을 했을 경우, 네비게이션바에 로그인이 로그아웃으로 변경되도록 base.html파일을 수정한다
'Programming > django' 카테고리의 다른 글
Django 게시판 만들기 (5) - 회원가입 구현 (0) | 2022.04.05 |
---|---|
Django 게시판 만들기 (3) - bootstrap 적용 (0) | 2022.04.01 |
Django 게시판 만들기 (2) - django mysql 연동 (0) | 2022.03.31 |
Django 게시판 만들기 (1) - 개발환경 구축(가상환경, 장고 설치) (0) | 2022.03.31 |