8월 26일(금) room 추가/수정/삭제 , room 검색, room 상세페이지
1. room 추가/수정/삭제
2. 게시글 작성자일때만 (...)메뉴 보이기
2. room 상세페이지
3. room 검색
☝🏻 room 추가
1. 템플릿 추가
메인페이지에 룸추가 href 수정
#core/index.html
...
<!-- 글쓰기 추가 -->
<div>
<a href="{% url 'room_add' %}" class="add_btn">
+
</a>
</div>
...
room/templates/room_add.html(임시)
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Room 추가</title>
</head>
<body>
{% if error %}
<script>alert('{{error}}')</script>
{% endif %}
<div class="mx-auto container py-20 px-6">
<form action="{% url 'room_add' %}" method="post">
{% csrf_token %}
<div>
<label for="title">방제목</label><br>
<input type="text" name="title" id="title">
</div>
<div>
<label for="content">부제목</label><br>
<input type="text" name="sub_title" id="sub_title">
</div>
<div>
<label for="content">내용</label><br>
<textarea name="content" id="content" cols="30" rows="10"></textarea>
</div>
<div>
<label for="room_password">비밀방</label>
<input type="text" name="room_password" id="room_password" placeholder="숫자 5글자"
oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" />
</div>
<input type="submit" value="글쓰기">
</form>
</div>
</body>
</html>
- 메소드 post 방식
<form action="{% url 'room_add' %}" method="post">
- 자바스크립트 경고창띄우기
{% if error %}
<script>alert('{{error}}')</script>
{% endif %}

2. room 추가 url 추가
#core/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('room/', views.room_add, name='room_add'), # 글추가
]
3. room 추가 뷰 추가
#room/views.py
from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required
#모델 가져오기
from room.models import Room
#글쓰기추가
@login_required
def room_add(request):
if request.method == 'POST': # post요청일 경우 if문 실행
title = request.POST.get('title', None)
sub_title = request.POST.get('sub_title', None)
content = request.POST.get('content', None)
room_password = request.POST.get('room_password', None)
room_owner = request.user
if not title:
return render(request, 'room_add.html', {"error" : "방제목를 입력 해주세요."})
if not sub_title:
return render(request, 'room_add.html', {"error" : "부제목을 입력 해주세요"})
if not content:
return render(request, 'room_add.html', {"error" : "내용을 입력 해주세요"})
if room_password:
if len(room_password) != 5: # 비밀번호는 필수가 아니지만 있을 경우 숫자 5글자
return render(request, 'room_add.html', {"error" : "방 비밀번호는 숫자 5글자로 설정해주세요"})
if (title and sub_title and content):
PostingObj = Room()
PostingObj.title = title
PostingObj.sub_title = sub_title
PostingObj.content = content
PostingObj.room_owner = room_owner
PostingObj.room_password =room_password
PostingObj.save() # 저장
return redirect('main') # core/views.py에 main함수 이동(메인페이지)
else:
return render(request, 'room_add.html', {"error" : "에러발생 모든 내용을 입력 해주세요"})
else:
return render(request, 'room_add.html')
☝🏻 room 수정
1. room 수정 뷰 추가
#room/views.py
from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required
#모델 가져오기
from room.models import Room
# 글 수정
@login_required
def room_edit(request,pk):
res_data = {}
try:
room = Room.objects.get(pk=pk)
except:
return render(request, 'room_edit.html', {'error' : "잘못된 접근입니다."})
user = request.user # 현재 로그인되어있는 유저
room_owner = room.room_owner # 포스팅 작성한 유저
res_data['room_owner'] = room_owner
if user == room_owner:
if request.method == 'POST':
res_data['room'] = room
title = request.POST['title']
sub_title = request.POST['sub_title']
content = request.POST['content']
if not title:
res_data['error'] = "제목을 입력 해주세요"
if not sub_title:
res_data['error'] = "부제목을 입력 해주세요"
if not content:
res_data['error'] = "내용을 입력 해주세요"
if (title and sub_title and content): #모두 입력했을 때
room.title = title
room.sub_title = sub_title
room.content = content
room.save() #저장
return redirect('main') #메인페이지로 이동
else:
res_data['error'] = "에러발생 모든 내용을 입력 해주세요"
return render(request, 'room_edit.html', res_data)
elif request.method == 'GET':
res_data['room'] = room
return render(request, 'room_edit.html', res_data)
else:
return render(request, 'index.html', {"error" : "권한이 없습니다."})
2. room 수정 url 추가
#core/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('room/', views.room_add, name='room_add'), # 글추가
path('room/edit/<int:pk>',views.room_edit, name="room_edit"), #글수정
]
3. 템플릿 추가
#room/room_edit.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Room 수정</title>
</head>
<body>
<div class="mx-auto container py-20 px-6">
<form method="post">
{% csrf_token %}
<div>
<label for="title">제목</label><br>
<input type="text" name="title" id="title" value="{{ room.title|safe }}">
</div>
<div>
<label for="content">방 비밀번호</label><br>
<input type="text" name="room_password" id="room_password" placeholder="*****"
oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" />
</div>
<div>
<label for="content">부제목</label><br>
<input type="text" name="sub_title" id="sub_title" value="{{ room.sub_title|safe }}">
</div>
<div>
<label for="content">내용</label><br>
<textarea name="content" id="content" cols="30" rows="10">{{ room.content|safe }}</textarea>
</div>
<input type="submit" value="수정하기"></a>
<button type="button">
<a href="/">뒤로가기</a>
</button>
</form>
</div>
</body>
</html>





☝🏻 room 삭제
현재 room [ ... ]드롭기능 <수정/삭제> 중 삭제 버튼 누르면 main.js 자바스크립트로 경고창에 "삭제됐습니다."문구 띄우고 확인 버튼만 있음
아직 만들고 계셔서 이 부분 나중에 다시 수정(문구띄우고 예/아니오 선택)하고, 지금은 삭제 버튼 누르면 바로 삭제되게끔 만들기
1. room 삭제 뷰 추가
# room/views.py
from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required
#모델 가져오기
from room.models import Room
# 글 삭제
@login_required
def room_delete(request, pk):
room = Room.objects.get(pk=pk)
if request.method == 'GET':
room.delete() #삭제
return redirect('main') # 메인페이지 이동
2. room 삭제 url 추가
# room/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('room/', views.room_add, name='room_add'), # 글추가
path('room/edit/<int:pk>',views.room_edit, name="room_edit"), #글수정
path('room/delete/<int:pk>',views.room_delete, name='room_delete'), #글삭제
]


☝🏻 게시글 작성자일때만 (...)메뉴 보이기
- core의 templates/index.html
#core/templates/index.html
...
<!-- 룸 수정/삭제 -->
{% if request.user.is_authenticated %} # 사용자의 로그인 여부를 확인
{% if r.room_owner == request.user %} # room의 room_owner가 현재 로그인 유저라면
<div class="setting_icon">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor"
class="bi bi-three-dots" viewBox="0 0 16 16">
<path
d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
</svg>
<div class="setting_icon-modal">
<div class="modal_box">
<p><a href="room/edit/{{ r.pk }}" class="room_modify">수정</a></p>
<p><a href="room/delete/{{ r.pk }}" class="room_remove">삭제</a></p>
</div>
</div>
</div>
{% endif %}
{% endif %}
...

☝🏻 room 상세페이지
1. room 상세페이지 뷰 추가
방장/방제/부제/내용/작성일
수정/삭제
#room/views.py
# 글 상세페이지
def room_page(request, pk):
room_pk = Room.objects.get(pk=pk)
res_data = { 'room': room_pk }
return render(request, 'room_page.html',res_data)
2. room 상세페이지 url 추가
#room/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('room/page/<int:pk>', views.room_page, name='room_page'), #글상세페이지
path('room/', views.room_add, name='room_add'), # 글추가
path('room/edit/<int:pk>',views.room_edit, name="room_edit"), #글수정
path('room/delete/<int:pk>',views.room_delete, name='room_delete'), #글삭제
]
3. 템플릿 추가
#room/templates/room_page.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Room 상세페이지</title>
</head>
<body>
<h5>방장 : {{ room.room_owner }}</h5>
<h5>방제 : {{ room.title }}</h5>
<h5>부제 : {{ room.sub_title }}</h5>
<h5>내용 : {{ room.content }}</h5>
<h5>작성일 : {{ room.create | date:"Y-m-d" }}</h5>
<!-- 수정/삭제 -->
{% if request.user == room.room_owner %} # 방장일 경우
<div>
<button type="button">
<a href="{% url 'room_edit' room.pk %}">수정</a>
</button>
<button type="button">
<a href="{% url 'room_delete' room.pk %}">삭제</a>
</button>
</div>
{% elif request.user != posts.room_owner %}
<div>
<button type="button">
<a href="/">가입하기</a>
</button>
</div>
{% endif %}
</body>
</html>


☝🏻 room 검색바
1. room 검색 뷰 추가
from django.shortcuts import render,redirect
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Q
#모델 가져오기
from room.models import Room
# 검색하기
@csrf_exempt
def search(request):
search_keyword = request.GET.get('q', None)
res_data = {}
if search_keyword: # 키워드 검색이 들어왔을때만 작동
if len(search_keyword) > 1:
room_list = Room.objects.all().order_by('-id')
search_posting_list = room_list.filter(
Q (title__icontains=search_keyword) | # 방제
Q (sub_title__icontains=search_keyword) | #부제
Q (content__icontains=search_keyword) | #내용
Q (room_owner__username__icontains=search_keyword) #방장
)
res_data['room'] = search_posting_list
else:
res_data['error'] = "검색어는 2글자 이상 입력해주세요."
else:
res_data['error'] = "검색 결과가 없습니다."
return render(request, "index.html", res_data)
2. room 검색 url 추가
#room/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('search',views.search, name="search"), #검색
path('room/page/<int:pk>', views.room_page, name='room_page'), #글상세페이지
path('room/', views.room_add, name='room_add'), # 글추가
path('room/edit/<int:pk>',views.room_edit, name="room_edit"), #글수정
path('room/delete/<int:pk>',views.room_delete, name='room_delete'), #글삭제
]
3. 템플릿 추가
#core/templates/index.html
...
<!-- 검색창 -->
<form class="d-flex main_search_form" role="search" action="{% url 'search' %}" method="get">
<div class="form_btnbox">
<input class="form-control" type="search" placeholder="스터디 모집 찾기" aria-label="Search" name="q" value="{{ q }}">
<button class="btn" type="submit">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
class="bi bi-search" viewBox="0 0 16 16">
<path
d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z" />
</svg>
</button>
</div>
</form>
...
<form class="d-flex main_search_form" role="search" action="{% url 'search' %}" method="get">
<input class="form-control" type="search" placeholder="스터디 모집 찾기" aria-label="Search" name="q" value="{{ q }}">

