Skip to content

Latest commit

ย 

History

History
198 lines (154 loc) ยท 9.51 KB

File metadata and controls

198 lines (154 loc) ยท 9.51 KB

์ด์ œ๋Š” ๋ณธ๊ฒฉ์ ์œผ๋กœ CRUD๋ฅผ ๋ฐฐ์šธ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. CRUD๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ปดํ“จํ„ฐ ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ๊ฐ€์ง€๋Š” ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์ธ Create(์ƒ์„ฑ), Read(์ฝ๊ธฐ), Update(๊ฐฑ์‹ ), Delete(์‚ญ์ œ)๋ฅผ ๋ฌถ์–ด์„œ ์ผ์ปซ๋Š” ๋ง์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ด๋ฏธ ๋งŒ๋“ค์—ˆ๋” Blog ๊ฐ์ฒด๋“ค์„ Read๋กœ ๋จผ์ € ํ™•์ธํ•ด๋ณด๊ณ , Create๋ฅผ ๋ฐฐ์›Œ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ ์ „์— GET๋ฐฉ์‹๊ณผ POST๋ฐฉ์‹์— ๋Œ€ํ•ด ๋จผ์ € ์งš์–ด๋ณด๊ณ  ๋„˜์–ด๊ฐˆ๊ฒŒ์š”.

GET vs POST

GET๋ฐฉ์‹์€ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป๊ธฐ ์œ„ํ•œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. URL์— ๋ณ€์ˆ˜๋ฅผ ํ‘œํ•จ์‹œ์ผœ ์š”์ฒญํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ, ๋ฐ์ดํ„ฐ๊ฐ€ ๋…ธ์ถœ๋˜์–ด ๋ณด์•ˆ์— ์ทจ์•ฝํ•˜์ฃ . e.g. /hello/test.php?name1=value1&name2=value2

๋ฐ˜๋ฉด POST๋ฐฉ์‹์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณธ๋ฌธ(BODY)์— ํฌํ•จ๋˜๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ URL์— ๋…ธ์ถœ๋˜์ง€ ์•Š์•„ ๊ธฐ๋ณธ์ ์ธ ๋ณด์•ˆ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. CSRF ๊ณต๊ฒฉ ๋ฐฉ์ง€๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. CSRF ๊ณต๊ฒฉ(Cross Site Request Forgery)์€ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ทจ์•ฝ์  ์ค‘ ํ•˜๋‚˜๋กœ ์ธํ„ฐ๋„ท ์‚ฌ์šฉ์ž(ํฌ์ƒ์ž)๊ฐ€ ์ž์‹ ์˜ ์˜์ง€์™€๋Š” ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ณต๊ฒฉ์ž๊ฐ€ ์˜๋„ํ•œ ํ–‰์œ„(์ˆ˜์ •, ์‚ญ์ œ, ๋“ฑ๋ก ๋“ฑ)๋ฅผ ํŠน์ • ์›น์‚ฌ์ดํŠธ์— ์š”์ฒญํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค. CSRF ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ Django์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ csrf token์„ ์ด์šฉํ•˜๋ฉฐ, POST ์š”์ฒญ์— ๋Œ€ํ•ด์„œ๋งŒ csrf token์„ ๋ฐœ๊ธ‰ํ•˜๊ณ  ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค.

1. Views.py

from django.shortcuts import render
from .models import Blog # Blog import ํ•ด์ฃผ๊ธฐ

def showmain(request):
    blogs = Blog.objects.all() # blogs๋ผ๋Š” ๋ณ€์ˆ˜์— Blog์˜ ๋ชจ๋“  ๊ฐ์ฒด๋“ค ๋‹ด๋Š”๋‹ค.
    return render(request, 'main/mainpage.html',{'blogs':blogs})
 

models.py์˜ Blog๋ฅผ ๋งŒ๋“œ์‹œ import ํ•ด์ฃผ์–ด์•ผ ์ธ์‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ ํ›„ showmainํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•ด์ค„๊ฒŒ์š”. ๋จผ์ € blogs๋ผ๋Š” ๋ณ€์ˆ˜์— Blog์˜ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๋‹ด์Šต๋‹ˆ๋‹ค. ๊ทธ ๋‹ค์Œ main์•ฑ์˜ mainpage.html์— blogs๋ผ๋Š” ์ด๋ฆ„(key)์œผ๋กœ ์•„๊นŒ Blog์˜ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๋‹ด์•˜๋˜ blogs(value)๋ฅผ ๋ณด๋‚ด์ค๋‹ˆ๋‹ค.

๐Ÿ’ก render์˜ ์„ธ ๋ฒˆ์งธ ์ธ์ž๋กœ๋Š” Python์˜ ๋”•์…”๋„ˆ๋ฆฌ(dictionary) ํƒ€์ž…์˜ ๊ฐ’์„ ๋„ฃ์–ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”•์…”๋„ˆ๋ฆฌ ํƒ€์ž…์€ {'key':value}์˜€์ฃ . ์ด ๊ณผ์ •์„ ํ•ด์•ผ mainpage.html์—์„œ blogs๋ฅผ ์ธ์‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. mainpaige.html

{% extends 'base.html' %}
{% load static %}

{% block content %}
    <h1>2021 Dongguk Likelion 3rd session</h1>
    <a href="{% url 'first' %}">first</a>
    <a href="{% url 'second' %}">second</a>
    <img src="{% static 'images/image01.jpg' %}">

<h1>๊ธ€ ๋ชฉ๋ก</h1>
<div>
    {% for blog in blogs %} <!-- blogs์˜ ๊ฐ์ฒด๋“ค์„ blog๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด ๋ฐ˜๋ณตํ•œ๋‹ค. -->
    <div>
        <h3>
            {{blog.title}} <br> <!-- ๊ทธ ๊ฐ์ฒด ํ•˜๋‚˜ blog์˜ ์†์„ฑ title์„ ๋„์›Œ์ค€๋‹ค. -->
            {{blog.writer}}<br> <!-- ๊ทธ ๊ฐ์ฒด ํ•˜๋‚˜ blog์˜ ์†์„ฑ writer๋ฅผ ๋„์›Œ์ค€๋‹ค. -->
            {{blog.body}} <!-- ๊ทธ ๊ฐ์ฒด ํ•˜๋‚˜ blog์˜ ์†์„ฑ body๋ฅผ ๋„์›Œ์ค€๋‹ค. -->
        </h3>
    </div>
    {% endfor %}
</div>

{% endblock %}

shomain ํ•จ์ˆ˜์—์„œ blogs์— Blog์˜ ๋ชจ๋“  ๊ฐ์ฒด๋“ค์„ ๋‹ด์•„์„œ ๋ณด๋‚ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด ๊ฐ์ฒด๋“ค์„ for๋ฌธ์„ ํ†ตํ•ด ํ™”๋ฉด์— ํ‘œ์‹œํ•ด์ค„๊ฒŒ์š”. blogs์˜ ์—ฌ๋Ÿฌ ๊ฐ์ฒด๋“ค์„ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด blog๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋‹ด์•„์„œ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ ค์ค๋‹ˆ๋‹ค.

โœ๏ธ ํ…œํ”Œ๋ฆฟ ํƒœ๊ทธ base.html ์ƒ์†, url, include ํ•  ๋•Œ ๋งŽ์ด ๋ดค๋˜ ํ…œํ”Œ๋ฆฟ ํƒœ๊ทธ {% %}์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ–ˆ๋˜ ํ…œํ”Œ๋ฆฟ ํƒœ๊ทธ๋Š” ๋‹ซ์ง€ ์•Š์•„๋„ ๋์ง€๋งŒ, for, if๋ฌธ์€ ๋ฐ˜๋“œ์‹œ ๋‹ซ์•„์ฃผ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

โœ๏ธ ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜ html์— ๋ณ€์ˆ˜๊ฐ€ ํ‘œ์‹œ๋˜๊ฒŒ ํ•˜๋ ค๋ฉด ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜์ธ ์ค‘๊ด„ํ˜ธ 2๊ฐœ {{ }}๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 3์ฃผ์ฐจ ์„ธ์…˜์—์„œ ํ…œํ”Œ๋ฆฟ ์–ธ์–ด์—๋Š” ๋ณ€์ˆ˜, ํ•„ํ„ฐ, ํƒœ๊ทธ, ์ฃผ์„ 4๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ฐฐ์› ์ฃ ? ๊ทธ ์ค‘ ๋‚ด์šฉ์„ ๊ฐ€์ ธ์˜ค๋Š” ์—ญํ• ์„ ํ•˜๋Š” ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด์˜ ์†์„ฑ์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ์ด์ „์— shell์—์„œ ORM์„ ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ .์„ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

3. ๋ณธ๋ฌธ ์•ž๋ถ€๋ถ„ ๋‚ด์šฉ๋งŒ ๋ณด์ด๊ฒŒ ํ•˜๊ธฐ

๋ณธ๋ฌธ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ๋ฉด ์•ž๋ถ€๋ถ„ ๋ช‡๊ธ€์ž๋งŒ ๋ณด์ด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. models.py์˜ Blogํด๋ž˜์Šค๋กœ ๋‹ค์‹œ ๊ฐ€์„œ summary ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

class Blog(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=200)
    writer = models.CharField(max_length=100)
    pub_date = models.DateTimeField(auto_now_add=True)
    body = models.TextField()

    def __str__(self):
        return self.title

    def summary(self):
        return self.body[:20] # ๊ฐ์ฒด ์ž๊ธฐ์ž์‹ ์˜ body์†์„ฑ์˜ ์ฒ˜์Œ(0)๋ถ€ํ„ฐ 19๊นŒ์ง€ slicingํ•˜์—ฌ ๋ฆฌํ„ด

โœ๏ธ Python slicing

A[start:end:step]

start: ์‹œ์ž‘ ์œ„์น˜, end: ๋๋‚ผ ์œ„์น˜, step: ๊ฐ„๊ฒฉ(๋ณดํญ) index๋Š” 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ณ , end-1๊นŒ์ง€ ์ž๋ฆ…๋‹ˆ๋‹ค. ๊ฐ„๊ฒฉ์€ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด 1์ž…๋‹ˆ๋‹ค.

๋‹ค์‹œ mainpage.html ๋‚ด์šฉ๋„ ์ˆ˜์ •ํ•ด์ค๋‹ˆ๋‹ค.

{% extends 'base.html' %}
{% load static %}

{% block content %}
    <h1>2021 Dongguk Likelion 3rd session</h1>
    <a href="{% url 'first' %}">first</a>
    <a href="{% url 'second' %}">second</a>
    <img src="{% static 'images/image01.jpg' %}">

<h1>๊ธ€ ๋ชฉ๋ก</h1>
<div>
    {% for blog in blogs %} <!-- blogs์˜ ๊ฐ์ฒด๋“ค์„ blog๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด ๋ฐ˜๋ณตํ•œ๋‹ค. -->
    <div>
        <h3>
            {{blog.title}} <br>
            {{blog.writer}}<br> 
            {{blog.summary} <!-- body์—์„œ summary๋กœ ๋ณ€๊ฒฝ -->
        </h3>
    </div>
    {% endfor %}
</div>

{% endblock %}

4. ์ƒ์„ธ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

views.py

๊ฐ์ฒด๋งˆ๋‹ค ๋‚ด์šฉ์„ ์ „๋ถ€ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ƒ์„ธ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. basic/main/views.py

from django.shortcuts import get_object_or_404, render # import get_object_or_404 

def detail(request, id):
    blog = get_object_or_404(Blog, pk = id) # id์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ์—†๋‹ค๋ฉด 404 ์—๋Ÿฌ
    return render(request, 'detail.html', {'blog':blog}) 
    

์ด์ œ๋Š” views ์— detail ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ด๋ณผ๊ฒŒ์š”. ๊ธฐ์กด์—๋Š” request๋งŒ ๋“ค์–ด์˜ค๋ฉด ๋ฐ”๋กœ html ํŒŒ์ผ์„ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฐ€๋Šฅํ–ˆ์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ๋ช‡ ๋ฒˆ์งธ ๊ฐ์ฒด์ธ์ง€๋„ ๊ฒฐ์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜๋ฏ€๋กœ id ๋„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ๋Š” id ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์™€์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์ฒ˜๋Ÿผ objects ๋กœ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋˜๋ฉด ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ get_obejct_or_404 ์ž…๋‹ˆ๋‹ค. ์œ„์—์„œ imort๋ฅผ ๋จผ์ € ํ•ด์ฃผ๊ณ , ์ด ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋Š”๋ฐ ์ฒซ๋ฒˆ์งธ๋กœ ์–ด๋–ค ํด๋ž˜์Šค์—์„œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ์ง€, ๋‘๋ฒˆ์งธ๋กœ ์•ž์˜ ํด๋ž˜์Šค์˜ ๋ช‡๋ฒˆ์งธ ๊ฐ์ฒด์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ช‡ ๋ฒˆ์งธ ๊ฐ์ฒด์ธ์ง€๋Š” pk(primary key) ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. pk๋Š” ๊ฐ ๊ฐ์ฒด๋ฅผ ๊ตฌ๋ถ„ํ•ด์ฃผ๋Š” ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.

urls.py

basic/basic/urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.showmain, name="showmain"),
    path('first/', views.first, name="first"),
    path('second/', views.second, name="second"),
    path('<str:id>', views.detail, name="detail"),
]

view๋ฅผ ์ •์˜ํ•ด์คฌ์œผ๋‹ˆ url์„ ํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ ๋‹ฌ๋ผ์ง„ ์ ์€ <str:id>์ž…๋‹ˆ๋‹ค. id๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๊ฐ’์„ str(๋ฌธ์ž์—ด) ํƒ€์ž…์œผ๋กœ ์ฃผ์†Œ๋กœ ๋ณด๋‚ธ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„์„ ๋ฐ”๋กœ path converter ๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ ์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๊ฐ์ฒด๋“ค์„ ๋‹ค๋ฃจ๋Š” ๊ณ„์ธต์ ์ธ url์„ ์ž๋™์œผ๋กœ ์‰ฝ๊ณ  ํŽธํ•˜๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ๋ฒˆ์งธ ๊ธ€์˜ ์ƒ์„ธ ํŽ˜์ด์ง€์™€ ๋‘๋ฒˆ์งธ ๊ธ€์˜ ์ƒ์„ธ ํŽ˜์ด์ง€ url์€ ๋‹ฌ๋ผ์•ผ๊ฒ ์ฃ . ๋˜ํ•œ, ํ•˜๋‚˜์˜ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฒฝ์šฐ์˜ ํŽ˜์ด์ง€๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด์˜ url์€ ๊ธฐ๋ณธ์ ์œผ๋กœ str ํƒ€์ž…์œผ๋กœ ์ธ์‹์„ ํ•ฉ๋‹ˆ๋‹ค. id๊ฐ’์€ ์ •์ˆ˜์ด๋ฏ€๋กœ <int:id>๋กœ ํ•ด์ฃผ์–ด๋„ ์ข‹์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ views.py์—์„œ show ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ id๊ฐ’์„ ๋ฐ›๋Š”๋‹ค๊ณ  ํ–ˆ์—ˆ์ฃ . ์—ฌ๊ธฐ์„œ id๊ฐ€ ๋ฐ”๋กœ ์ด urls.py์˜ id์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์˜ url ๋กœ ์ ‘์†์‹œ id๋ฅผ views ์— detail ํ•จ์ˆ˜๋กœ ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด detailํ•จ์ˆ˜๋Š” id์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด๋ฅผ blog๋ผ๋Š” ๋ณ€์ˆ˜์— ๋‹ด๊ณ , ์—†๋‹ค๋ฉด 404์—๋Ÿฌ๋ฅผ ๋„์šฐ๊ฒ ์ฃ . ๋งŒ์•ฝ <str:blog_id> ์˜€๋‹ค๋ฉด views.py์—๋„ def detatil(request,blog_id)์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

mainpaige.html

{% extends 'base.html' %}
{% load static %}

{% block content %}
    <h1>2021 Dongguk Likelion 3rd session</h1>
    <a href="{% url 'first' %}">first</a>
    <a href="{% url 'second' %}">second</a>
    <img src="{% static 'images/image01.jpg' %}">

<h1>๊ธ€ ๋ชฉ๋ก</h1>
<div>
    {% for blog in blogs %}
    <div>
        <h3>
            {{blog.title}} <br>
            {{blog.writer}}<br>
            {{blog.summary}}
            <a href="{% url 'detail' blog.id %}">...์ž์„ธํžˆ</a>
        </h3>
    </div>
    {% endfor %}
</div>

{% endblock %}

์ƒ์„ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํŠผ์˜ ๋งํฌ๋ฅผ ์—ฐ๊ฒฐํ•ด์ค๋‹ˆ๋‹ค. blog.id๋ฅผ ํ†ตํ•ด id๊ฐ’์„ URL ๋’ค์— ๋ถ™์—ฌ์„œ ๋ณด๋‚ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ ์•„๊นŒ ์ž‘์„ฑํ•œ detail์ด๋ผ๋Š” ์ด๋ฆ„์˜ url์—์„œ id๋ฅผ ๋ฐ›์•„ detailํ•จ์ˆ˜๋กœ ๋ณด๋‚ด์ค„ํ…Œ๊ณ , ๊ทธ๋ž˜์•ผ deatailํ•จ์ˆ˜๊ฐ€ id์— ๋งž๋Š” ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ blog๋ผ๋Š” ์ด๋ฆ„์— ๋‹ด์•„ deatil.html๋กœ ๋ณด๋‚ด์–ด ๋„์›Œ์ค„ ์ˆ˜ ์žˆ๊ฒ ์ฃ .

detail.html

basic/main/templates/main/detail.html์„ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ์ƒ์„ธ ํŽ˜์ด์ง€์˜ template์ด์—์š”.

{% extends 'base.html' %}
{% load static %}

{% block content %}

<h1>
    {{blog.titile}}
    ์ž‘์„ฑ์ž: {{blog.writer}}
    ๋‚ ์งœ: {{blog.pub_date}}
</h1>
<p>{{blog.body}}</p>

{% endblock %}

READ ์™„๋ฃŒ!