본문 바로가기

💡웹 프로젝트/(백엔드)Django - 프로젝트01

프로젝트01. bootstrap 적용하기

Bootstrap을 적용한 웹사이트를 만들어, 기존에 만들어 놓은 memo웹사이트와 마찬가지로 다음 세가지 기능을 구현해보겠습니다.

1, 글 쓰기 기능

2. 글 목록 보기 기능

3. 글 디테일 보기 기능

+) 추가로 기존의 memo웹사이트로 가는 url도 메뉴에 추가해보겠습니다.

 

목차

  • <urls.py 분리>
  • <bootstrap 적용>
  • 1. bootstrap 적용
  • 2. 블로그에 글 작성
  • 3. admin사이트에 category, post생성 + 글 추가하기
  • 4. admin사이트에서 작성한 글 블로그에 나타내기
  • 5. 글 작성하는 폼('widget_tweaks'이용) 만들기 + 로그인 PostcreateVIew생성
  • 6. 결과

 

<urls.py 분리>

urls.py 분리 : mysite/urls.py에 simp_web/urls.py 연결

1) mysite/urls.py

from django.contrib import admin
from django.conf.urls import include, url

from django.urls import path
from django.views.generic import RedirectView
from django.conf import settings
from django.conf.urls.static import static

#http://127.0.0.1:8000/simp_web
urlpatterns = [
    path('admin/', admin.site.urls),
    path('simp_web/', include('simp_web.urls')),
    #path("", RedirectView.as_view(url="/simp_web/", permament=True)),
    path("", RedirectView.as_view(url="/simp_web/")),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) #static설정

 

2) simp_web/urls.py

from django.urls import path
from simp_web import views
from simp_web.views import CreatememoView, MemolistView, MemodetailView, UpdatememoView, DeletememoView

urlpatterns = [
    path('page', views.page, name='page'),
    path('memo', views.memo, name='memo'),
    path('memo/create', CreatememoView.as_view(), name='add'),
    path('memo/memolist', MemolistView.as_view(), name='memolist'),
    path('memolist/detail/<int:pk>', MemodetailView.as_view(), name='detail'),
    path('memolist/update/<int:pk>', UpdatememoView.as_view(), name='update'),
    path('memolist/delete/<int:pk>', DeletememoView.as_view(), name='delete'),
]

 

<bootstrap 적용하기>

1. bootstrap 적용

1-1) bootstrap 다운받기

 

1-2) views.py와 urls.py에 index, single 작성

  • views.py에 내용추가
from django.shortcuts import render
from django.views import generic

# Create your views here.

def index(request):
    context = {
       
    }
    return render(request, 'index.html', context=context)
    
def single(request):
    context = {
       
    }
    return render(request, 'single.html', context=context)
  • simp_web/urls.py에 내용추가
urlpatterns = [
    path('', views.index, name='index'),
    path('single', views.single, name='index'),
]

 

1-3) 결과

  • index.html

  • single.html

 

 

2. 블로그에 글 작성

2-1) category, post 모델 생성

  • models.py
from django.db import models
from django.urls import reverse

# Create your models here.
class Category(models.Model):  #category모델 생성
    name = models.CharField(max_length=50, help_text='글의 분류를 입력하세요.(ex: 간단한 메모)')

    def __str__(self):
        return self.name

class Post(models.Model):  #post모델 생성
    title = models.CharField(max_length=200)
    title_image = models.ImageField(blank=True)
    content = models.TextField()
    createDate = models.DateTimeField(auto_now_add=True)
    updateDate = models.DateTimeField(auto_now=True)
    category = models.ManyToManyField(Category, help_text='글의 분류를 설정하세요.')

    def __str__(self):
        return self.title

 

2-2) 이미지 모듈설치

cmd에 pip install Pillow입력

 

2-3) 미디어 설정 추가

  • settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
  • mysite> urls.py
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) #추가

 

2-4) db에 변경사항 저장

  • cmd에 python manage.py makemigrations입력
  • python manage.py migrate입력

 

 

3. admin사이트에 category, post생성 + 글 추가하기

  • admin.py
from django.contrib import admin
from .models import Category, Post

admin.site.register(Category)
admin.site.register(Post)

 

 

4. admin사이트에서 작성한 글 블로그에 나타내기

  • views.py
from django.views.generic import DetailView

def index(request):
    #최근 작성한 글 내림차순으로 5개 불러오기
    post_latest = Post.objects.order_by("-createDate")[:5]
    context = {
        "post_latest" : post_latest
    }

    return render(request, 'index.html', context=context)

class PostDetailView(DetailView):
    model = Post
  • simp_web> urls.py
path('single', views.single, name='index'), #을
path("post/<int:pk>", views.PostDetailView.as_view(), name="post"), #로 변경
  • index.html, single.html(post_detail.html로 이름변경)의 세부내용 바꾸기
  • 템플릿 index와 single에서 쓰이는 모델 작성

models.py

class Post(models.Model):
    title = models.CharField(max_length=200)
    title_image = models.ImageField(blank=True)
    content = models.TextField()
    createDate = models.DateTimeField(auto_now_add=True)
    updateDate = models.DateTimeField(auto_now=True)
    category = models.ManyToManyField(Category, help_text='글의 분류를 설정하세요.')

    def __str__(self):     
        return self.title

    #1번 글의 경우 -> post/1
    def get_absolute_url(self):
        return reverse("post", args=[str(self.id)])

    #content가 200자 이상?
    def is_content_more200(self):
        return len(self.content) > 200
        
    #300자가 넘어가면 200자까지만 출력
    def get_content_under200(self):
        return self.content[:200]

 

 

5. 글 작성하는 폼('widget_tweaks'이용) 만들기 + 로그인 PostcreateVIew생성

5-1) 글 작성 폼 만들기

  • 템플릿 post_form.html 생성(필요없는 내용 삭제 후 작성)
<h2>새 글 작성하기</h2>
<form action="" method="post" enctype="multipart/form-data">
  {% csrf_token %}
  <table>
    {{ form.as_table }}
  </table>
  <input type="submit" value="저장">
</form>
  • urls.py에 글 작성하는 url연결
path("post/create", views.PostCreateView.as_view(), name="post_create"),   #추가
  • views.py에 PostCreateView생성
from django.views.generic.edit import CreateView

class PostCreateView(LoginRequiredMixin, CreateView):  #추가
    model = Post
    fields = ['title', 'title_image', 'content', 'category']
  • index.html, post_detail.html에서 글 작성하기 링크를 HOME옆에 만들기

 

5-2) 로그인한 사람만 글 작성 폼 나타내기

  • index.html에 로그인한 사람만 글 작성하는 하이퍼링크 나타내기 설정
{% if user.is_authenticated %}
#로그인이 되어있을 때 "글 작성하기" 나타내기
  <li class="nav-item">
    <a class="nav-link" href="{% url 'post_create' %}">글 작성하기</a>
  </li>
{% else %}
#로그인이 안되어있을 떄 "로그인하기" 나타내기
  <li class="nav-item">
    <a class="nav-link active" href="/admin">로그인하기</a>
  </li>
{% endif %}

 

5-3) 글 작성하는 폼 더 이쁘게 만들기(widget_tweaks이용)

  • cmd에 pip install django-widget-tweaks입력
  • settings.py\installed_apps에 'widget_tweaks', #추가
  • index.html, post_form.html에
{% load static %} #이부분아래 아래 부분 추가
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
  • post_form.html의 폼부분 이쁘게 수정하기
<h2>새 글 작성하기</h2>
{% load widget_tweaks %}  #widget_tweaks이용
<form action="" method="post" enctype="multipart/form-data">
  {% csrf_token %}
  {% for field in form.visible_fields %} #views.py에 설정한 필드
  <div class="form.group">
    <label for="{{field.id_for_label}}">{{field.label}}</label>
    {{field|add_class:'form-control'}}
    {%  for error in field.errors %}
    <span class="help-block">{{error}}</span>
    {% endfor %}
  </div>
  {% endfor %}
  <input type="submit" value="저장">
</form>

 

5-4) 템플릿 중 중복되는 부분 묶어서 템플릿으로 처리하기(base_generic.html)

base_generic.html index.html, post_detail.html, post_form.html

중복되는 부분

{% block content %}
{% endblock %}

 

중복되는 부분

{% extends 'base_generic.html' %}
{% block content %}

   내용 부분

 

{% endblock %}

 

 

6. 결과

6-1) index.html

6-2) post_detail.html

6-3) post_form.html

6-4) 기존의 memo웹사이트 가는 메뉴부분