FrameWork/Django

8월 26일(금) room 추가/수정/삭제 , room 검색, room 상세페이지

print(blue) 2022. 8. 27. 00:34

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>
유저일 경우 / 방장인 경우&nbsp;


☝🏻 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 }}">

http://127.0.0.1:8000/search?q=이건