# Remind & Practice

img

Django๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์ด ๊ฐœ๋ฐœ๋˜์–ด ์˜คํ”ˆ์†Œ์Šคํ™” ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์ด๋“œ๋ฅผ ์ž˜ ์ฝ์–ด๋ณด๋ฉด ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์ธ CKEditor(opens new window) ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด๋ด…์‹œ๋‹ค!

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด ๋จผ์ € static file ๊ด€๋ จ ์„ค์ •์ด ์™„๋ฃŒ๋œ ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” ์ œ๊ฐ€ ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ Remindํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

# 1.blog_ckeditor ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ

$ python -m venv ckeditor_venv # ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ

$ source ckeditor_venv/Scripts/activate # ๊ฐ€์ƒํ™˜๊ฒฝ ์‹คํ–‰

$ pip install django # django ์„ค์น˜

$ django-admin startproject blog_ckeditor #ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

$ python manage.py startapp 'blogapp' # app ์ƒ์„ฑ

$ python manage.py runserver # http://127.0.0.1:8000/

# 2. ํ”„๋กœ์ ํŠธ์— App ์—ฐ๊ฒฐํ•˜๊ธฐ

settings.py์— app ์•Œ๋ฆฌ๊ธฐ

# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blogapp.apps.BlogappConfig', # Add
]

# 3. App - template ๋งŒ๋“ค๊ธฐ

๊ฒฝ๋กœ : blogapp/templates/index.html

์ด๋ฒˆ์—” ์žฌ๋ฏธ๋กœ Cover๋ฅผ ๋„ฃ์–ด๋ดค์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ์ ์šฉ์‹œ์ผœ๋ณด์…”๋„ ์ข‹์•„์š”.

index.html ์ „์ฒด์ฝ”๋“œ(opens new window)

cover.css ์ „์ฒด์ฝ”๋“œ(opens new window)


๊ฒฝ๋กœ : blogapp/templates/blogmain.html

index ํŽ˜์ด์ง€๋Š” ๋‚˜์ค‘์— ํ™œ์šฉํ•˜๋ ค๊ตฌ ๋งŒ๋“ค์—ˆ๊ณ 

CKEditor๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•œ blog home์€ ๋”ฐ๋กœ ์ž‘์„ฑํ• ๊ฒŒ์š”!

index.html ์ „์ฒด์ฝ”๋“œ(opens new window)

cover.css ์ „์ฒด์ฝ”๋“œ(opens new window)

# static file ๊ฒฝ๋กœ

img


# 4. App - view ๋งŒ๋“ค๊ธฐ

์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด home.html ํŒŒ์ผ์„ ์—ด์–ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ blog ํด๋” ๋‚ด๋ถ€์— views.pyํŒŒ์ผ์— ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

from django.shortcuts import render

def index(request):
    return render(request, 'index.html')

def blogMain(request):
    return render(request, 'blogMain.html')

# 5. URLconf ์—ฐ๊ฒฐ

๋‹ค์Œ์€ url์„ ์—ฐ๊ฒฐํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

urls.py ํŒŒ์ผ์„ ์—ด์–ด ๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

from django.contrib import admin
from django.urls import path
import blogapp.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blogapp.views.index, name='index'),
    path('blogMain/', blogapp.views.blogMain, name='blogMain'),
]

# 6.static file ์ ์šฉ

๋ถ€ํŠธ์ŠคํŠธ๋žฉ file์„ static file๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ๊ฒ ์ฃ .

์ด์ „ ํฌ์ŠคํŒ…์—์„œ ๋‹ค๋ค˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ ์ ์šฉ์‹œํ‚ฌ๊ฒŒ์š”!

# blog_ckeditor/settings.py
import os

# ...

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'blogapp', 'static')
]

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# โนcollectstatic ์‹คํ–‰

$ python manage.py collectstatic

์„œ๋ฒ„๋ฅผ ์‹คํ–‰์‹œ์ผœ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ์ ์šฉ์ด ์ž˜ ๋˜์—ˆ๋Š”์ง€ ํ•œ๋ฒˆ์”ฉ ํ™•์ธํ•ด๋ณด์„ธ์š”!

img

img


# 7.๋ธ”๋กœ๊ทธ ๋ฉ”์ธ ์ปจํ…์ธ  ๊ตฌ์„ฑ

  • ๊ธ€์“ฐ๊ธฐ
  • ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ
  • ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ

๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ์€ ๋‚˜์ค‘์— ๊ผญ ๊ตฌํ˜„ํ•ด๋ณด์„ธ์š”!

# โนindex.html ์ˆ˜์ •

๋ธ”๋กœ๊ทธ์— ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค ์ฃผ์†Œ์— ๊ณ„์† [http://127.0.0.1:8000/blogMain/]์„ ์ณ์„œ ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์€ ๋ฒˆ๊ฑฐ๋กœ์šฐ๋‹ˆ ๋งํฌ๋ฅผ ๊ฑธ์–ด์„œ ๋„˜๊ฒจ๋ด…์‹œ๋‹ค.

์ €๋Š” ๊ฐ€์šด๋ฐ [Learn more] ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ฉ”์ธ ํ™”๋ฉด์œผ๋กœ ๋„˜์–ด๊ฐ€๋„๋ก ๊ตฌ์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

img

[index.html] ๋ฌธ์„œ๋ฅผ ์—ด๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

<a href="{% url 'blogMain' %}" class="btn btn-lg btn-secondary">Learn more</a>

img

# โนblogMain.html ์ˆ˜์ •

๋ธ”๋กœ๊ทธ ๋ฉ”์ธ ์ปจํ…์ธ  ๊ธฐ๋Šฅ๋Œ€๋กœ ์ถ”๊ฐ€ํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • cover๋กœ ๋Œ์•„๊ฐ€๋Š” ๋งํฌ
<a class="navbar-brand" href="{% url 'index' %}">Likelion HUFS 8th</a>
  • ๋ธ”๋กœ๊ทธ main ๋งํฌ
<a class="nav-link" href="{% url 'blogMain' %}">Home <span class="sr-only">(current)</span></a>
  • ๊ธ€์“ฐ๊ธฐ, ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ navbar
<li class="nav-item">
    <a class="nav-link" href="#">๊ธ€์“ฐ๊ธฐ</a>
</li>
<li class="nav-item">
    <a class="nav-link" href="#">๋กœ๊ทธ์ธ</a>
</li>
<li class="nav-item">
    <a class="nav-link" href="#">๋กœ๊ทธ์•„์›ƒ</a>
</li>

img


# 8. App - models.py ์ž‘์„ฑ

๋ธ”๋กœ๊ทธ ์ž‘์„ฑํ•  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋˜‘๊ฐ™์ด ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ œ๋ชฉ
  • ๋‚ด์šฉ
  • ์ž‘์„ฑ์ผ์ž

blogapp ํด๋” ๋‚ด์—์„œ models.py๋ฅผ ์—ด์–ด

์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ์ค๋‹ˆ๋‹ค.

from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=100)
    pub_date = models.DateTimeField()
    body = models.TextField()

# 9. Database migration

database ๋ชจ๋ธ์„ ์ž‘์„ฑํ•œ ์ดํ›„์—๋Š” ํ•ญ์ƒ ๋‹ค์Œ ๊ณผ์ •์„ ๊ฑฐ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. models.py์—์„œ ์ฝ”๋“œ ์ž‘์„ฑ
  2. python manage.py makemigrations ์„ ํ†ตํ•ด migration ๋งŒ๋“ค๊ธฐ
  3. python manage.py migrate ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ์šฉํ•˜๊ธฐ
$ python manage.py makemigrations
$ python manage.py migrate

# 10. Admin ์ƒ์„ฑ

๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ด€๋ฆฌ์žadmin๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ด…์‹œ๋‹ค.

$ python manage.py createsuperuser
  • ์ด๋ฆ„
  • ์ด๋ฉ”์ผ
  • ๋น„๋ฐ€๋ฒˆํ˜ธ
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ

# 11. Admin์— model ๋“ฑ๋กํ•˜๊ธฐ

blog ํด๋” ์•ˆ์œผ๋กœ ๋“ค์–ด๊ฐ€์„œ admin.py๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

from django.contrib import admin
from .models import Blog

# Register your models here.
admin.site.register(Blog)

# 12. Admin page์—์„œ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑํ•˜๊ธฐ

img


# 13. view๋กœ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

model์„ ๋งŒ๋“ค๊ณ  ๊ทธ ์•ˆ์— ๋ฐ์ดํ„ฐ๋„ ๋„ฃ์—ˆ์œผ๋ฉด ์ด๊ฑธ template์œผ๋กœ ๋ณด๋‚ด ๋ณด์—ฌ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ model์—์„œ template์œผ๋กœ ๋ฐ”๋กœ ๋‚ด์šฉ์„ ๋ณด๋‚ผ์ˆ˜๋Š” ์—†๊ณ  ํ•ญ์ƒ view๋ฅผ ๊ฑฐ์ณ์„œ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

์ด๋ฒˆ์—” form์„ ๋”ฐ๋กœ ์ž‘์„ฑํ•ด ๋ชจ๋ธ์˜ ํ•ญ๋ชฉ์„ ๊ฐ€์ ธ์˜ค๋Š” ์ž‘์—…์„ ํ•ด๋ณด์•„์š”.

form ์—์„œ ๊ธ€์“ฐ๊ธฐ์— ์‚ฌ์šฉํ•  ํผ์„ ๋งŒ๋“ค๊ณ  ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ƒ์„ฑํ• ๊ฒ๋‹ˆ๋‹ค.

# โนforms.py ๋งŒ๋“ค๊ธฐ

# blogapp/forms.py ์ƒ์„ฑ!

from django import forms
from .models import Blog

class CreateBlog(forms.ModelForm):
    class Meta:
        model = Blog

        fields = ['title', 'pub_date', 'body']

# โนํ…œํ”Œ๋ฆฟ๊ณผ view ๋žœ๋”๋ง

# createBlog.html

  • /blogapp/templates/createBlog.html ์ƒ์„ฑ

# urls.py

  • blog_ckeditor/urls.py ์ˆ˜์ •
from django.contrib import admin
from django.urls import path
import blogapp.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blogapp.views.index, name='index'),
    path('blogMain/', blogapp.views.blogMain, name='blogMain'),
    path('blogMain/createBlog/', blogapp.views.createBlog, name='createBlog'),
]

# blogMain.html ์—ฐ๊ฒฐ

  • blogapp/blogMain.html ์ˆ˜์ •
<li class="nav-item">
    <a class="nav-link" href="{% url 'createBlog' %}">๊ธ€์“ฐ๊ธฐ</a>
</li>

# views.py ์ˆ˜์ •

  • blogapp/views.py ์ˆ˜์ •
from django.shortcuts import render
from .forms import CreateBlog

def index(request):
    return render(request, 'index.html')

def blogMain(request):
    return render(request, 'blogMain.html')

def createBlog(request):
    form = CreateBlog()
    return render(request, 'createBlog.html', {'form' : form})
  • [blogapp]-[views.py]์—์„œ [createBlog] ํ•จ์ˆ˜๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ถˆ๋Ÿฌ๋“ค์ธ ํผ์„ [createBlog.html]์œผ๋กœ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด [form]์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ณด๋‚ด์ค๋‹ˆ๋‹ค.
  • ์ง€๊ธˆ๊นŒ์ง€๋Š” render(request, 'ํ…œํ”Œ๋ฆฟ') ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•˜์˜€์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ์„ธ๋ฒˆ์งธ ์ธ์ž๊ฐ€ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ธ๋ฒˆ์งธ ์ธ์ž๋Š” [context]๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด๋ฉฐ, ๋”•์…”๋„ˆ๋ฆฌ ์ž๋ฃŒํ˜•์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ด๋Š” [createBlog.html] ๋ฌธ์„œ์— ๋”•์…”๋„ˆ๋ฆฌ ์ž๋ฃŒํ˜•์„ ๋ณด๋‚ด๊ฒŒ ๋˜๊ณ , [createBlog.html]์—์„œ๋Š” ์žฅ๊ณ  ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ’์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

# โนcreateBlog.html ์ˆ˜์ •ํ•˜๊ธฐ

  • ์œ„์—์„œ ๋”•์…”๋„ˆ๋ฆฌ ์ž๋ฃŒํ˜•์œผ๋กœ [form]์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜์˜€์œผ๋ฏ€๋กœ ํ‚ค ๊ฐ’ 'form'์„ ์ด์šฉํ•˜์—ฌ ์ถœ๋ ฅํ•ด๋ด…์‹œ๋‹ค. html ๋ฌธ์„œ์—์„œ ์ถœ๋ ฅํ•  ๋•Œ์—๋Š” ์žฅ๊ณ  ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  • ํ˜•ํƒœ๋Š” ์™€ ๊ฐ™์€ ํ˜•์‹์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์ƒํ™ฉ์— ๋”ฐ๋ผ ์žฅ๊ณ  ํ…œํ”Œ๋ฆฟ์„ ํ™œ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์šฐ๋ฆฌ๋Š” ์ผ๋‹จ ๊ทธ๋ƒฅ ๊ฐ’์„ ์ถœ๋ ฅํ•ด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Form</title>
</head>
<body>
    {{ form.as_p }}
</body>
</html>

img


# 14. Templates - DB ์—ฐ๋™

  • ์ง€๊ธˆ๊นŒ์ง€ ํ•œ ์ž‘์—…๋“ค์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ์ƒ์„ฑ ์ดํ›„๋ถ€ํ„ฐ ์ •๋ฆฌํ•˜์—ฌ๋ด…์‹œ๋‹ค.
  1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ์„ ์ƒ์„ฑ
  2. ๊ทธ ๋ชจ๋ธ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ ํผ์„ ์ƒ์„ฑ
  3. ๋ทฐ์—์„œ ์œ„์˜ ํผ์„ ๋ถˆ๋Ÿฌ ๋“ค์ด๊ณ  ํ…œํ”Œ๋ฆฟ์— ์ „๋‹ฌ
  4. ํ…œํ”Œ๋ฆฟ์—์„œ ํ™”๋ฉด์— ์ถœ๋ ฅ
  • ์ด์ œ๋ถ€ํ„ฐ ํ•ด์•ผ๋˜๋Š” ์ž‘์—…์€ ํ…œํ”Œ๋ฆฟ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ, ์ด ๋ฐ์ดํ„ฐ๋“ค์ด ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ์ด ๋˜์–ด์•ผํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค.

  • ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์—์„œ๋Š” ๋‹จ์ง€ [Save] ๋ฒ„ํŠผ๋งŒ ๋ˆ„๋ฅด๋ฉด ์ €์žฅ์ด ๋˜์—ˆ์ง€๋งŒ, ์ง€๊ธˆํ•˜๊ณ  ์žˆ๋Š” ์ž‘์—…๋“ค์€ ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

# โนcreateBlog.html ์ˆ˜์ •

  • ํ˜„์žฌ [createBlog.html] ๋ฌธ์„œ์—๋Š” ๋‹จ์ง€ ํผ์„ ์ถœ๋ ฅํ•˜๋Š” ์ฝ”๋“œ๋งŒ์ด ์žˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค.
  • ๋ฌผ๋ก  ์ง€๊ธˆ๋„ ํผ์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์™”๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค.
  • html์—์„œ๋Š” ์‚ฌ์šฉ์ž๋“ค์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด
    ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๋„ ์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ํผ์„ ๊ตฌ์ถ•ํ•ด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.
<form method="POST">
    {{ form.as_p }}
    <input type="submit" value="์ €์žฅ"/>
</form>

# โนviews.py - createBlog() ์ˆ˜์ •

[blogapp]-[views.py]๋กœ ๋Œ์•„์™€์„œ createBlog() ํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์ œ๋Œ€๋กœ DB์— ์ €์žฅํ•˜๋„๋ก ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

from django.shortcuts import render, redirect
from .forms import CreateBlog

def index(request):
    return render(request, 'index.html')

def blogMain(request):
    return render(request, 'blogMain.html')

def createBlog(request):
 
    if request.method == 'POST':
        form = CreateBlog(request.POST)
 
        if form.is_valid():
            form.save()
            return redirect('blogMain')
        else:
            return redirect('index')
    else:
        form = CreateBlog()
        return render(request, 'createBlog.html', {'form': form})
 
    # form = CreateBlog()
    # return render(request, 'createBlog.html', {'form': form})

img

์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.

img

# โนcsrf_token

Django๋Š” POST ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๊ณผ์ •์—์„œ ๋ณด์•ˆ์„ ์œ„ํ•ด csrf_token์ด ์—†์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ์ฒ˜๋ฆฌ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ) CSRF(Cross-Site Request Forgery)๋ž€?(opens new window) - ์‚ฌ์ดํŠธ_๊ฐ„_์š”์ฒญ_์œ„์กฐ

ํ•œ ์ค„์„ ๋” ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

{% csrf_token %}

img

์ถ”๊ฐ€ํ•ด์ฃผ๊ณ  Admin ํŽ˜์ด์ง€์—์„œ ์ž˜ ์ €์žฅ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

img

# 15.Template ์ƒ์†

์ด์ „ ์„ธ์…˜์—์„œ ๋งŽ์ด ๋‹ค๋ฃจ์—ˆ๊ธฐ ๋–„๋ฌธ์— ์ ์šฉ๋งŒ ํ•˜๊ณ  ๋„˜์–ด๊ฐˆ๊ฒŒ์š”!

๊ธ€์“ฐ๊ธฐ ํŽ˜์ด์ง€๋„ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ํ…œํ”Œ๋ฆฟ์„ ์ƒ์†๋ฐ›์•„์„œ ์ž‘์„ฑํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

  • blog_ckeditor/templates ์ƒ์„ฑ
  • base.html ์ƒ์„ฑ
  • blogMain.html ๋‚ด์šฉ base.html๋กœ ๋ณต๋ถ™

์šฐ๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ณตํ†ต ๋ถ€๋ถ„์ธ nav๋ถ€๋ถ„์„ base๋กœ ๋ฌถ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

base.html ๋‚ด์šฉ

{% load static %}
<head>
  <link
    rel="stylesheet"
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
    integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
    crossorigin="anonymous"
  />
  <link rel="stylesheet" href="{% static 'css/navbar-top-fixed.css' %}" />
</head>
<body>
  <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
    <a class="navbar-brand" href="{% url 'index' %}">Likelion HUFS 8th</a>
    <button
      class="navbar-toggler"
      type="button"
      data-toggle="collapse"
      data-target="#navbarCollapse"
      aria-controls="navbarCollapse"
      aria-expanded="false"
      aria-label="Toggle navigation"
    >
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarCollapse">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link" href="{% url 'blogMain' %}"
            >Home <span class="sr-only">(current)</span></a
          >
        </li>
        <li class="nav-item">
          <a class="nav-link" href="{% url 'createBlog' %}">๊ธ€์“ฐ๊ธฐ</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">๋กœ๊ทธ์ธ</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">๋กœ๊ทธ์•„์›ƒ</a>
        </li>
      </ul>
      <form class="form-inline mt-2 mt-md-0">
        <input
          class="form-control mr-sm-2"
          type="text"
          placeholder="Search"
          aria-label="Search"
        />
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">
          Search
        </button>
      </form>
    </div>
  </nav>

{% block content %}
 
{% endblock %}

</body>

๋งจ ์•„๋ž˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด

{% block content %}
{% endblock %}

์ƒ์† ํ…œํ”Œ๋ฆฟ ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ blogMain.html ๊ณผ createBlog.html ํŒŒ์ผ์— ์ƒ์† ํ‚ค์›Œ๋“œ๋ฅผ ์ ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

blogMain.html ๋‚ด์šฉ

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

<main role="main" class="container">
  <div class="jumbotron">
    <h1>๋ฉ‹์Ÿ์ด์‚ฌ์ž์ฒ˜๋Ÿผ HUFS</h1>
    <p class="lead">CKEditor๋ฅผ ์œ„ํ•œ ๋ธ”๋กœ๊ทธ ํ™ˆ</p>
    <a
      class="btn btn-lg btn-primary"
      href="{{ site.baseurl }}/docs/{{ site.docs_version }}/components/navbar/"
      role="button"
      >Button Click &raquo;</a
    >
  </div>
</main>

{% endblock %}

createBlog.html ๋‚ด์šฉ

{% extends 'base.html' %}
{% block content %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Form</title>
  </head>
  <body>
    <form method="POST">
      {% csrf_token %} {{ form.as_p }}
      <input type="submit" value="์ €์žฅ" />
    </form>
  </body>
</html>

{% endblock %}

์„œ๋ฒ„๋ฅผ ๋Œ๋ ค๋ณด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ ์šฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

img


์—ฌ๊ธฐ๊นŒ์ง€ ๋ฆฌ๋งˆ์ธ๋“œ ๋ฐ ๊ธฐ๋ณธ ์„ค์ • ๋!

Last Updated: 9/25/2020, 10:50:12 PM