리우's IT Story
article thumbnail
728x90
반응형

2023.04.16 - [파이썬을 이용한 웹구축] - 파이썬 게시글 목록과 댓글 css(bootstrap) html

 

파이썬 게시글 목록과 댓글 css(bootstrap) html

웹페이지 디렉토리를 코드로 열기 터미널 cmd 상태에서 ..\test\scripts\activate 우선 서버를 python manage.py runserver를 입력해서 서버를 열어준다. 게시글 목록이 정상적으로 열리는지 확인. 어제는 게시

ji7290.tistory.com

 

이전에는 게시글 목록과 댓글에 css를 넣어주고 작성버튼을 만들어주었다. 

 

 

 게시글 작성할 수 있는 폼을 만들어보자. 

post method를 사용해야 전달되는 데이터를 보호할 수 있다.

 

board로가서 form.py를 생성해 준다

 모델 클래스를 쓸꺼면  클래스안에 메타클래스가 반드시 있어야한다. 

 

views.py로 돌아가서 

QuestionForm을 import시켜준다. 

from .forms import QuestionForm

forms에 있는 questionForm을 갖다쓰겠다.

 

def c_question(request):
    form = QustionForm()
    return render(request, 'board/q_form.html', {'form':form})

 

폼을 작성할 수 있는 함수를 만들어주고

반환값은  board/q_form.html으로 넘겨준다. 

 

 

board 폴더에다가  -  q_form.html을 생성해준다.

 

마찬가지로 q_form에도 base.html이 적용되도록 

 

템플릿 태그를 작성해주고 

   폼태그는 메소드 post 메서드로 로 작성

    {% csrf_token %} 필수태그도 작성

endblock태그까지 마무리해준다.

 

웹이미지

게시글 목록에서 글 작성버튼을 클릭하면 이렇게 글 작성 영역이 만들어진다. 

 

하지만 글을 채우고 글 작성하기 버튼을 누르면  게시글 목록에 추가는 아직 되지 않고있다. 

 submit으로 제출은했지만 데이터에 저장을 못하고 있다. 

 

views.py로 가서 코드를 수정해주자

 

c_question부분을 이렇게 수정해준다. 

 

def c_question(request):
    if request.method == 'POST':
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.create_date = timezone.now()
            question.save()
            return redirect('board:index')
    else:
        form = QuestionForm()
    context = {'form' : form}
    return render(request, 'board/q_form.html', context)

 

글작성이 정상적으로 리스트에 보여지게 된다. 

 

q_form에서 

form태그로 서버에 넘겨준다. 

 

{% extends 'base.html' %}
{% block content %}
<div class="container">
    <h4 class="my-3 border-bottom pb-2">글 작성 </h4>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn btn-primary">글 작성하기
    </form>
</div>

post형식으로  넘겨주면 

    path('question/create/', views.c_question, name='c_question'),

c_question함수가 동작을해서 

 

from django import forms
from board.models import Question

class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ['subject', 'content']
       

 

post된 항목을 가지고 QuestionForm항목을만들어서 사용하겠다. 

def c_question(request):
    if request.method == 'POST':
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.create_date = timezone.now()
            question.save()
            return redirect('board:index')
    else:
        form = QuestionForm()
    context = {'form' : form}
    return render(request, 'board/q_form.html', context)

 

#함수에서 return을 만나는 순간 함수는 종료가 된다. 

 

최초의 글작성 눌렀을때는 else가 동작을 하고 

    else:
        form = QuestionForm()
    context = {'form' : form}
    return render(request, 'board/q_form.html', context)

 

그 이후에 글 내용을 작성해서 글작성버튼을 누르면 

 q_form에 post라는 메소드가 데이터를 전송하게 되고 

 <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn btn-primary">글 작성하기
    </form>

 

urls.py 에서

urlpatterns = [
    path('question/create/', views.c_question, name='c_question'),

path경로가 동작을해서

 

views.py에 

 

c_question 함수 -> if함수가 동작을 하게되고 

def c_question(request):
    if request.method == 'POST':
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.create_date = timezone.now()
            question.save()
            return redirect('board:index')

if함수 

만약에 form안의 내용이 유효하다면

question이 받은 3개의 필드의 데이터를 save로 저장을 한후 

            question = form.save(commit=False)
            question.create_date = timezone.now()
            question.save()

 

return render로 board의 인덱스 q_list 화면으로 보내는 것이다. 

            return redirect('board:index')

 

이제 글 작성페이지를 꾸며보자. 

 

forms.py로 가자 

from django import forms
from board.models import Question

class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ['subject', 'content']
        widgets = {
            'subject' : forms.TextInput(attrs={'class': 'form-control'}),
            'content' : forms.Textarea(attrs={'class': 'form-control', 'rows' : 10 }),
        }
        labels = {
            'subject' : '제목',
            'content' : '내용',
        }
       

widgets을 만들어쓰는이유는 q_forms에서 자동으로 만들어지게 해놔서

form에서 직접적인 지정이 불가능하다.

웹이미지

 

 

q_form에서 widgets을 사용해보자.

 

q_form을 수정해준다. 

<form method="post">
        {% csrf_token %}
        <!--    form에서 widgets사용시
               {{ form.as_p }}
        -->
        {% if form.errors %}
        <div class="alert alert-danger" role="alert">
            {% for field in form %}
            {% if field.errors %}
            <div>
                <strong>{{ field.label }}</strong>
                {{ field.errors }}
            </div>
            {% endif %}
            {% endfor %}
        </div>
        {% endif %}
        <div class="mb-3">
            <label for="subject" class="form-label">제목</label>    
            <input type="text" class="form-control" name="subject" id="subject"
                    value="{{ form.subject.value|default_if_none:'' }}">
        </div>
        <div class="mb-3">
            <label for="content" class="form-label">내용</label>
            <textarea class="form-control" name="content" id="content" rows="10">
                    {{ form.content.value|default_if_none:'' }}
            </textarea>
        </div>
     

 forms.py 의 widgets 영역은  주석을 걸어준다. 

 

우선 웹에서  http://127.0.0.1:8000/board/  페이지로 이동해준다. 

내용을 입력하지않고 글 작성버튼을 누르면  

    {% if form.errors %}
        <div class="alert alert-danger" role="alert">
            {% for field in form %}
            {% if field.errors %}
            <div>
                <strong>{{ field.label }}</strong>
                {{ field.errors }}
            </div>
            {% endif %}
            {% endfor %}
        </div>

 

이 코드가 동작하게되어서 

 

제목과 내용을 필수항목으로 입력하라고 요청 alert를 띄워준다. 

 

 

 <div class="mb-3">
            <label for="subject" class="form-label">제목</label>    
            <input type="text" class="form-control" name="subject" id="subject"
                    value="{{ form.subject.value|default_if_none:'' }}">
        </div>

 

subject 데이터에 값이 없을경우에  none대신 공백을 띄워놔라 

                   value="{{ form.subject.value|default_if_none:'' }}"

 

만약 제목에 value값을 이렇게 지정해놓는다면 

  <div class="mb-3">
            <label for="subject" class="form-label">제목</label>    
            <input type="text" class="form-control" name="subject" id="subject"
                    value="{{ form.subject.value}}">

 

이렇게 none으로 뜨게되서 매번 none을 지우고 입력해야겠지만

 

다시  코드를 수정해서 none 값 ' ' blank로 가려주면

                   value="{{ form.subject.value|default_if_none:'' }}"

 

사용자가 처음부터 입력할 수 있도록 칸이 비워지게된다. 

 

답변을 등록할 수 있게 코드를 작성해보자.

forms.py파일을 수정하자

 

AnswerForm 클래스 안에

   필수 Meta 클래스를 만들어주고 

모델은 Answer로 

필드는 content로 받아준뒤 

 content = 댓글내용으로 수정해준다. 

 

class AnswerForm(forms.ModelForm):
    class Meta:
        model = Answer
        fields= ['contents']
        labels = {
            'content' : '댓글내용'
        }
       

 

views.py로가서 c_answer함수를 수정해주자

 

httpResponseNotAllowed와

AnswerForm을 import시켜준다

from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.http import HttpResponse, HttpResponseNotAllowed
from .models import Question
from .forms import QuestionForm
from .forms import AnswerForm
 

 

 

        return HttpResponseNotAllowed('Only POST is possible.')

get을 요청하지못하게 만들었다.

 

 

q_detail.html을 수정하자.

        <div class="mb-3">

=>           <div class="form-group my-3">

 

 {% endfor %}
    <form action="{% url 'board:c_answer' question.id %}" method="POST" class="my-3">
        {% csrf_token %}
        <div class="form-group my-3">
            <label for="content" class="form-label">댓글내용</label>
            <textarea name="content" id="content" class="form-control" rows="5"></textarea>
        </div>
        <div class="d-flex justify-content-end">
            <input type="submit" value="댓글작성" class="btn btn-primary">
        </div>
    </form>
</div>
{% endblock %}

class를 수정해주고 

댓글작성버튼을 오른쪽으로 뜨게 수정해준다. 

 

django 테스트

댓글작성폼 수정

 

q_detail로가서 댓글창이 비워있으면  경고문을 띄울수 있도록 수정해보자 

 

{% endfor %}
    <form action="{% url 'board:c_answer' question.id %}" method="POST" class="my-3">
        {% csrf_token %}
        {% if form.errors %}
        <div class="alert alert-danger" role="alert">
            {% for field in form %}
            {% if field.errors %}
            <div>
                <strong>{{ field.label }}</strong>
                {{ field.errors }}
            </div>
            {% endif %}
            {% endfor %}
        </div>

댓글 쪽 for문 안에 

조건문을 써서 django 내장객체인 alert경고문으로 경고창을 띄울 수 있도록 바꾸어줬다. 

지금은 단일게시판이라고 생각했을때 아무런 문제가 되지않지만

사이트가 확장되면서 그 중의 게시판 하나다 라고 한다면  게시판목록을 띄워야한다. 

 

 다음시간에는 부트스트랩 네비게이션바를 사용해서 게시글을 컨트롤 할 수 있게 해보자. 

 

 

https://getbootstrap.kr/

 

Bootstrap

강력하고 확장 가능하며 기능이 풍부한 프론트엔드 툴킷. Sass로 빌드 및 커스터마이징하고, 사전 빌드된 그리드 시스템 및 구성 요소를 활용하고, 강력한 JavaScript 플러그인으로 프로젝트에 생기

getbootstrap.kr

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형
profile

리우's IT Story

@LRWoo

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!