프로젝트/장고 웹페이지 구축

[Django] 포스트 작성 페이지 구현하기 - (1)

eunjuu 2023. 9. 27. 03:06
728x90

🧾 감히 역대급 난이도라고 자신할 수 있는 포스트 작성 페이지 구현하기

거짓말 안 치고 챗 지피티한테 질문 백 번 정도 한 것 같다. 사실 지금은 껍데기만 구현한 거고 세부적인 기능은 (ex. 로그인한 사용자만 작성하기 등) 아주 나중에 추가할 예정이다.


WRITE 버튼을 누르면 !

/assignments/advanced/

이런 식으로 뜨는 건데 . . . ㅎㅎ

/assignments/advanced/create/

 

Submit 버튼 누르면 위와 같은 에러 발생

 

*Submit 버튼 누르면 에러 페이지가 뜬다. 근데 결론적으로...  저장이 되긴 됨.

 

1~5번 게시물이 WRITE 이용해서 새로 작성한 것

 

📎 참고한 사이트 : https://velog.io/@wodnr0710/Do-it-%EC%9E%A5%EA%B3%A0-%EB%B6%80%ED%8A%B8%EC%8A%A4%ED%8A%B8%EB%9E%A9-15%EC%9E%A5.-%ED%8F%BC%EC%9C%BC%EB%A1%9C-%ED%8F%AC%EC%8A%A4%ED%8A%B8-%EC%9E%91%EC%84%B1%EA%B3%BC-%EC%88%98%EC%A0%95-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

 

[Do it 장고 + 부트스트랩] 15장. 폼으로 포스트 작성과 수정 구현하기

15장에서는 form을 사용해 여러 방문자가 새로운 글을 작성하고 수정할 수 있는 페이지를 구현하는 방법을 배운다.

velog.io

 


🤍 models.py

from django.db import models
from django.conf import settings
from markdownx.models import MarkdownxField

# author은 settings 의 User 테이블 사용

class BasicAssignment(models.Model): # models 모듈의 Model 클래스를 확장하여 만든 클래스
    title = models.CharField(max_length=200)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
    content = MarkdownxField()
    file_upload = models.FileField(upload_to='uploads/', null=True, blank=True, default='default_value.pdf')
    created_at = models.DateTimeField(auto_now_add=True)
    view_count = models.PositiveIntegerField(default=0)

    def __str__(self):
        return self.title

class AdvancedAssignment(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
    content = MarkdownxField()
    file_upload = models.FileField(upload_to='uploads/', null=True, blank=True, default='default_value.pdf')
    created_at = models.DateTimeField(auto_now_add=True)
    view_count = models.PositiveIntegerField(default=0)

    def __str__(self):
        return self.title

1. 마크다운 파트는 일단 이 포스팅에서는 크게 신경 쓸 필요가 없다.

2. 파일 업로드 할 수 있는 코드를 추가했다.

 file_upload = models.FileField(upload_to='uploads/', null=True, blank=True, default='default_value.pdf')

* 이 코드 그대로 따라할 거면 'pip install django-markdownx'를 터미널에 입력해서 설치한 후 순서대로 'python manage.py makemigrations' 'python manage.py migrate' 해주면 된다.

 

🤍 Views.py

from django.urls import reverse_lazy # Submit 기능 쓰려고 추가한 것인데,,, 일단 안 됨
from django.shortcuts import render, get_object_or_404
from django.views.generic.edit import CreateView # 이거 추가됨!!!!!!
# View에 Model(Post 게시글) 가져오기
from .models import BasicAssignment, AdvancedAssignment
from django.core.paginator import Paginator

#... 중간 생략

# 작성 페이지 class 2개 새로 추가
class BasicCreate(CreateView):
    model = BasicAssignment
    fields = ['title', 'content', 'file_upload']
    template_name = 'assignments/submit.html'  # 기본 템플릿 설정

class AdvancedCreate(CreateView):
    model = AdvancedAssignment
    fields = ['title', 'content', 'file_upload']
    template_name = 'assignments/submit.html'  # 기본 템플릿 설정
    success_url = reverse_lazy('advancedlist')  # 성공 시 리디렉션할 URL 지정... 근데 아직 안 됨

장고가 제공하는 CreateView 를 상속받아서 BasicCreate, AdvancedCreate라는 클래스를 만든다. CreateView는 CRUD작업에서 "Create" 기능을 구현하는 데 일반적으로 사용된다. BasicCreate 과 AdvancedCreate 는 클래스가 각각 다른 모델과 필드를 사용하였지만, 동일한 템플릿 'assignments/submit.html'을 공유하게 했다.

 

🤍 Urls.py

from django.urls import path
from .views import BasicBlog, BasicPosting, AdvancedBlog, AdvancedPosting, BasicCreate, AdvancedCreate

urlpatterns = [
    #.. 앞에꺼 생략
    
    # BasicCreate 뷰에 대한 URL 패턴을 추가합니다.
    path('assignments/basic/create/', BasicCreate.as_view(), name='basic_create'),

    # AdvancedCreate 뷰에 대한 URL 패턴을 추가합니다.
    path('advanced/create/', AdvancedCreate.as_view(), name='advanced_create'),

]

 

🤍 Advancedlist.html

<div class="col-lg-12">
	<div class="main-button">
    	<a href="{% url 'advanced_create' %}"> WRITE </a>
    </div>
</div>

advancedlist.html에서 WRITE 버튼을 누르면 submit.html로 넘어간다! 코드는 버튼 부분만 공유,,

 

🤍 Submit.html

  <div class="game-details">
    <div class="row">
        <div class="col-lg-12">
            <div id="assignment-content" class="content assignment-container">
                <div class="row">
                    <div class="container">
                        <h3 class="assignment-title">Create New Advanced Assignment</h3>
                        <form method="post" enctype="multipart/form-data" class="assignment-form">
                            {% csrf_token %}
                            {{ form.as_p }}
                            <button type="submit" class="assignment-submit-button">Submit</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
  </div>

* {% csrf_token %}은 웹 사이트를 CSRF 공격으로부터 보호하기 위해 장고가 제공하는 기능

/* 기본 컨테이너 스타일 */
#assignment-content {
    padding: 120px;
    border-radius: 5px;
}

/* 제목 스타일 */
.assignment-title {
    font-size: 30px;
    margin-top: 40px;
    margin-bottom: 20px;
    text-align: left; /* 텍스트 좌측 정렬 */
}

/* 폼 스타일 */
.assignment-form {
    margin-top: 10px;
}

/* 폼 필드 스타일 */
.assignment-field {
    width: 100%;
    padding: 10px;
    margin-bottom: 10px;
    border: 1px solid #ccc;
    border-radius: 3px;
}

/* 제출 버튼 스타일 */
.assignment-submit-button {
    margin-top: 20px;
    background-color: #366F31;
    color: #fff;
    padding: 10px 20px;
    border: none;
    border-radius: 3px;
    cursor: pointer;
}

/* 제출 버튼 호버 효과 */
.assignment-submit-button:hover {
    background-color: #0C2F09;
}

일단 1차로 여기까지 구현했다. 다음에는 조금 더 develop 시켜서 오는 걸로!

728x90