๐Ÿฆ๋ฉ‹์Ÿ์ด ์‚ฌ์ž์ฒ˜๋Ÿผ 11๊ธฐ/๋ฐฑ์—”๋“œ๋ฅผ ์œ„ํ•œ Django Rest Framework

Chapter3 Django๋กœ Todo ๋ชฉ๋ก ์›น ์„œ๋น„์Šค ๋งŒ๋“ค๊ธฐ

1son 2023. 4. 7. 07:27
3.1 Todo ๋ชฉ๋ก ์›น ์„œ๋น„์Šค ์‹œ์ž‘ํ•˜๊ธฐ

์žฅ๊ณ ๋ฅผ ํ™œ์šฉํ•ด ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ด๋ฉฐ ์ค‘์š”ํ•œ Todo ๋ชฉ๋ก ์›น ์„œ๋น„์Šค ์˜ˆ์ œ๋ฅผ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

3.1.1 ํ”„๋กœ์ ํŠธ ๊ธฐ๋Šฅ ์ •๋ฆฌํ•˜๊ธฐ 

Todo๋ชฉ๋ก ์„œ๋น„์Šค๋Š” CRUD๋กœ ๋ถˆ๋ฆฌ๋Š”, ๋ฐ์ดํ„ฐ ๊ด€๋ จ ์ฒ˜๋ฆฌ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ํฌํ•จ ๋ฐ ์ง๊ด€์ ์ด๊ณ  ๊ฐ„๋‹จ

์ดํ›„ DRF๋ฅผ ๊ณต๋ถ€ํ•œ ๋‹ค์Œ์— ๋˜‘๊ฐ™์€ ํ”„๋กœ์ ํŠธ๋ฅผ DRF ๋ฒ„์ „์œผ๋กœ ๊ฐœ๋ฐœํ•ด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

 

3.1.2 ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•˜๊ธฐ

๊ฐ€์ƒํ™˜๊ฒฝ ์„ธํŒ…

 

์žฅ๊ณ  ์„ค์น˜ 

 

์žฅ๊ณ  ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

 

todo ์•ฑ ์ƒ์„ฑ

 

 

3.1.4 Todo ํ”„๋กœ์ ํŠธ ์„ค์ •ํ•˜๊ธฐ 

๊ธฐ๋ณธ์ ์ธ ์„ค์ • ๋จผ์ € ์ง„ํ–‰ํ•˜๊ฒ ์Œ

todo ์•ฑ์„ ์ƒ์„ฑํ–ˆ์œผ๋ฏ€๋กœ settings.py์— ์•ฑ์„ ์ถ”๊ฐ€ํ•˜๊ฒ ์Œ

 

๋งˆ์ง€๋ง‰์œผ๋กœ

๋งˆ์ด๊ทธ๋ ˆ์ดํŠธ๋ฅผ ํ•ด์ค€ ๋’ค,

๊ด€๋ฆฌ์ž ๊ณ„์ •์„ ์ƒ์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

3.1.4 Todo ๋ชจ๋ธ ์ƒ์„ฑํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ์˜ ์ฒซ ๋‹จ๊ณ„๋Š” ์–ธ์ œ๋‚˜ ๋ชจ๋ธ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

์šฐ๋ฆฌ๊ฐ€ ์ƒ์„ฑํ•  ๋ชจ๋ธ์˜ ํ•„๋“œ๋ฅผ ์ƒ๊ฐํ•ด๋ณด๋ฉด 

1. title : Todo์˜ ์ œ๋ชฉ

2. description : Todo์— ๋Œ€ํ•œ ์„ค๋ช…

3. created : Todo ์ƒ์„ฑ ์ผ์ž

4. complete : Todo ์™„๋ฃŒ ์—ฌ๋ถ€

5. important : Todo ์ค‘์š” ์—ฌ๋ถ€

 

๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•œ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

todo ๋ฐ‘์— ๋ฐ”๋กœ ์žˆ๋Š” models.py ํŒŒ์ผ์— ์ ๋Š” ๊ฒƒ์ด๋‹ค! 

 

 

์ƒ์„ฑ์ผ์€ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€๋˜๋„๋ก ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

์žฅ๊ณ ๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” pk์ธ id ํ•„๋“œ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Œ์„ ์—ผ๋‘์— ๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

์ดํ›„์— ์šฐ๋ฆฌ๋Š” id ๊ฐ’์„ pk๋กœ ํ™œ์šฉํ•˜์—ฌ Todo ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ๋ถ„ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. 

 

์ด์ œ ๋ชจ๋ธ์— ๋Œ€ํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ํ›„ ์ตœ์ดˆ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด๋ฏ€๋กœ ๊ธฐ๋ณธ ๋ชจ๋ธ๊นŒ์ง€

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋  ์ˆ˜ ์žˆ๋„๋ก ์•ฑ์„ ์ง€์ •ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

 

๋ชจ๋ธ์„ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

todo/admin.py์—์„œ Todo ๋ชจ๋ธ์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. 

 

๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์— ์ ‘์†ํ•˜๋ ค๋ฉด url์ด ์„ค์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

mytodo/urls.py์—์„œ path๊ฐ€ ์ž˜ ์„ค์ •๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. 

 

 

์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 

 

 

3.2 Todo ์ „์ฒด ์กฐํšŒ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

์ฒซ๋ฒˆ์žฌ ๊ธฐ๋Šฅ์€ Todo ์ „์ฒด ์กฐํšŒ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. 

 

3.2.1 Todo ์ „์ฒด ์กฐํšŒ ๊ธฐ๋Šฅ ์ปจ์…‰

์ฒซ๋ฒˆ์งธ ํŽ˜์ด์ง€์ธ Todo ์ „์ฒด ์กฐํšŒ ๊ธฐ๋Šฅ์—์„œ๋Š” ์™„๋ฃŒ๋˜์ง€ ์•Š์€ Todo๋งŒ ๋ณด์—ฌ์ฃผ๋„๋ก ๊ตฌํ˜„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

3.2.2 Bootstrap์œผ๋กœ ์ข€ ๋” ๋ฉ‹์ง„ ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ 

๋ถ€ํŠธ์ŠคํŠธ๋žฉ์€ ๊ฐ€์žฅ ์œ ๋ช…ํ•˜๊ณ  ์˜ค๋ž˜๋œ CSSํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. 

 

3.2.3 Todo ์ „์ฒด ์กฐํšŒ ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ

์ž‘์—… ์ˆœ์„œ๋Š” ์•ž์„  ์˜ˆ์ œ์™€ ๋™์ผํ•˜๊ฒŒ ํ…œํ”Œ๋ฆฟ -> ๋ทฐ -> url ์ˆœ์„œ๋กœ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

<html>
    <head>
        <title>Todo ๋ชฉ๋ก ์•ฑ</title>
        <link
        rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        />
        <link rel="stylesheet" href="https://cdn.jsdeliver.net/npm/bootstrap-iocons@1.7.1/font/boot-strap-icons.css">

    </head>
    <body>
        <div class="container">
            <h1>Todo ๋ชฉ๋ก ์•ฑ</h1>
            <p>
                <a href=""><i class="bi-plus"></i>Add Todo</a>
                <a href="" class="btn btn-primary" style="float:right"> ์™„๋ฃŒํ•œ TODO ๋ชฉ๋ก</a>
            </p>
            <ul class="list-group">
                {% for todo in todos %}
                <li class="list-group-item">
                    <a href="">{{ todo.title }}</a>
                    {% if todo.important %}
                    <span class="badge badge-danger">!</span>
                    {% endif %}
                    <div style="float:right">
                    <a href="" class="btn btn-outline-primary">์ˆ˜์ •ํ•˜๊ธฐ</a>
                    </div>
                </li>
                {% endfor %}
            </ul>
        </div>
    </body>
</html>

์•ž์˜ ๊ฒƒ๊ณผ ๋‘๊ฐ€์ง€ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 

1. head ์•ˆ์— <link>ํƒœ๊ทธ๊ฐ€ ์žˆ๊ณ  ์—ฌ๊ธฐ์—์„œ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. 

2. ๊ฐ ํƒœ๊ทธ๋งˆ๋‹ค class ๋ผ๋Š” ๊ฒƒ์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

 

1๋ฒˆ์€ Bootstrap์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. 

๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€์ธ๋ฐ, 

์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ bootstrap ํ™ˆํŽ˜์ด์ง€์—์„œ cssํŒŒ์ผ๋“ค์„ ๋ฐ›์•„์™€ ํ”„๋กœ์ ํŠธ ํด๋”์— ์ง‘์–ด๋„ฃ๋Š” ๋ฐฉ์‹

๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ์›น ๋งํฌ ํ˜•ํƒœ๋กœ ์ œ๊ณต๋˜๋Š” cssํŒŒ์ผ์„ ๊ฐ€์ ธ๋‹ค ์“ฐ๋„๋ก ์ฐธ์กฐ์‹œํ‚ค๋Š” ๋ฐฉ์‹

 

3.2.4 Todo ์ „์ฒด ์กฐํšŒ ๋ทฐ ๋งŒ๋“ค๊ธฐ

๋‹ค์Œ์€ ๋ทฐ ์ž…๋‹ˆ๋‹ค. Todo ๋ฐ์ดํ„ฐ๋ฅผ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

์ด๋•Œ ์™„๋ฃŒ๋˜์ง€ ์•Š์€ Todo๋งŒ ์ „๋‹ฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— complete = False ์˜ต์…˜์œผ๋กœ ํ•„ํ„ฐ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์™„๋ฃŒ๋˜์ง€ ์•Š์€ Todo๋งŒ ์ „๋‹ฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— complete =False ์˜ต์…˜์œผ๋กœ ํ•„ํ„ฐ๋งํ•ด์•ผํ•จ

 

 

3.2.5 Todo ์ „์ฒด ์กฐํšŒ URL ์—ฐ๊ฒฐํ•˜๊ธฐ

๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋Š” url์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ Todo๋ชฉ๋ก์„ ๋ณด์—ฌ์ค„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์†Œ์— todo_list๋ทฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

path('', views.todo_list, name='todo_list')๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฃจํŠธ ๊ฒฝ๋กœ('')์— ๋Œ€ํ•œ ์š”์ฒญ์„ views.todo_list ํ•จ์ˆ˜์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฃจํŠธ URL์„ ๋ฐฉ๋ฌธํ–ˆ์„ ๋•Œ todo_list ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

๋˜ํ•œ ์•ž์„œ ์ž‘์„ฑํ•œ todo ์•ฑ์„ ํ”„๋กœ์ ํŠธ url์— ์—ฐ๊ฒฐํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. 

mytodo/urls.py์— todo.urls๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

 

path('todo/', include('todo.urls'))๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ '/todo/' ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ์š”์ฒญ์„ 'todo.urls'๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” 'todo' ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ •์˜๋œ URL ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ •์ž…๋‹ˆ๋‹ค. 'todo.urls'๋Š” 'todo' ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ์˜ URL ํŒจํ„ด์„ ์ •์˜ํ•˜๋Š” ๋ชจ๋“ˆ์˜ ๊ฒฝ๋กœ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

 

์ฒซ๋ฒˆ์งธ ๊ธฐ๋Šฅ์ธ Todo ์ „์ฒด ์กฐํšŒ ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!

 

 

3.3 Todo ์ƒ์„ธ ์กฐํšŒ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ
3.3.1 Todo ์ƒ์„ธ ์กฐํšŒ ๊ธฐ๋Šฅ ์ปจ์…‰

์ƒ์„ธ ์กฐํšŒ ๊ธฐ๋Šฅ์€ Todo๋ฅผ ์„ ํƒํ–ˆ์„ ๋•Œ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์œผ๋กœ, 

Todo ์ œ๋ชฉ๊ณผ ์„ค๋ช…์„ ๋‚˜ํƒ€๋‚ด๋„๋ก ๊ตฌํ˜„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

 

3.3.2 Todo ์ƒ์„ธ ์กฐํšŒ ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ

์ฒซ ๋‹จ๊ณ„๋Š” ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. ์•ž์„œ ๋งŒ๋“ค์—ˆ๋˜ ํ…œํ”Œ๋ฆฟ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ํ™œ์šฉ ํ•  ๊ฒƒ.

Todo ์ œ๋ชฉ๊ณผ ์„ค๋ช…์„ ๋ณด์—ฌ์ค„ ๊ฒƒ์ด๋ฉฐ ๋ชฉ๋ก์œผ๋กœ ๋‹ค์‹œ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ๋ฒ„ํŠผ์„ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค.

 

<html>
  <head>
    <title>TODO ๋ชฉ๋ก ์•ฑ</title>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
    />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
  </head>
  <body>
  <div class="container">
    <h1>TODO ์ƒ์„ธ๋ณด๊ธฐ</h1>
    <div class="container">
      <div class="row">
        <div class="col-md-12">
          <div class="card">
            <div class="card-body">
              <h5 class="card-title">{{ todo.title }}</h5>
              </h5>
              <p class="card-text">{{ todo.description }}</p>
              <a href="{% url 'todo_list' %}" class="btn btn-primary">๋ชฉ๋ก์œผ๋กœ</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
  </div>
</html>

 

 

 

3.3.3 Todo ์ƒ์„ธ ์กฐํšŒ ๋ทฐ ๋งŒ๋“ค๊ธฐ

๋‹ค์Œ ๋‹จ๊ณ„๋Š” ๋ทฐ์ž…๋‹ˆ๋‹ค.

์„ ํƒ๋œ Todo์˜ pk์ธ Id๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Todo๊ฐ์ฒด๋ฅผ ์ฐพ์•„

todo_detail.html๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

3.3.4 Todo ์ƒ์„ธ ์กฐํšŒ URL ์—ฐ๊ฒฐํ•˜๊ธฐ

๋งˆ์ง€๋ง‰์œผ๋กœ url์„ ์—ฐ๊ฒฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

url์€ /pk/๋กœ ์„ค์ •ํ•˜์—ฌ ํ•ด๋‹น Todo๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

path('<int:pk>/', views.todo_detail, name='todo_detail'):

  • <int:pk>๋Š” ์ •์ˆ˜ ํ˜•์‹์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ URL์—์„œ ์ˆซ์ž ๊ฐ’์„ ๋ฐ›์•„์™€์„œ pk๋ผ๋Š” ๋ณ€์ˆ˜์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • /์ˆซ์ž/ ํ˜•ํƒœ์˜ URL์— ๋Œ€ํ•œ ํŒจํ„ด์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • views.todo_detail ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๋‹น pk ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ํ•  ์ผ์˜ ์ƒ์„ธ ์ •๋ณด ํŽ˜์ด์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • name='todo_detail'๋Š” ์ด URL ํŒจํ„ด์— ๋Œ€ํ•œ ์ด๋ฆ„์„ 'todo_detail'๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ด๋ฆ„์€ URL ์—ญ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ํ•ด๋‹น URL์„ ์ฐธ์กฐํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค

 

3.4 Todo ์ƒ์„ฑ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ
3.4.1 Todo ์ƒ์„ฑ ๊ธฐ๋Šฅ ์ปจ์…‰

Todo ์ƒ์„ฑ์€ ์ œ๋ชฉ, ์„ค๋ช…, ์ค‘์š”๋„๋ฅผ ์ž…๋ ฅํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž…๋ ฅ ํผ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์•„๊นŒ ๋งŒ๋“ค์–ด๋†“์€ todo/forms.py์˜ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

3.4.2 Todo ์ƒ์„ฑ ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ 

todo/forms.py์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํผ์„ ํ™œ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์„ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

์•ž์„œ ๋งŒ๋“  ํผ์„ forms.as_P์˜ ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•˜๋ฉด ํƒœ๊ทธ ๊ผด๋กœ ํ…œํ”Œ๋ฆฟ์— ํผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. 

<html>
  <head>
    <title>TODO ๋ชฉ๋ก ์•ฑ</title>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
    />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
  </head>
  <body>
  <div class="container">
    <h1>TODO ์ถ”๊ฐ€ํ•˜๊ธฐ</h1>
    <div class="container">
      <div class="row">
        <div class="col-md-12">
          <div class="card">
            <div class="card-body">
              <form method="POST">
                {% csrf_token %} {{ form.as_p }}
                <button type="submit" class="btn btn-primary">๋“ฑ๋ก</button>
              </form>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
  </div>
</html>

 

3.4.3 Todo ์ƒ์„ฑ ๋ทฐ ๋งŒ๋“ค๊ธฐ

Todo๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋ทฐ๋Š” POST์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

POST ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ๋Š” ํผ์„ ๊ฒ€์ฆํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉฐ, 

GET ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ๋Š” ํผ์„ ํฌํ•จํ•œ ํ…œํ”Œ๋ฆฟ ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

  • if request.method == "POST": ์กฐ๊ฑด๋ฌธ์œผ๋กœ POST ์š”์ฒญ์ธ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • TodoForm(request.POST)์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ ํผ์„ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • form.is_valid()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํผ์ด ์œ ํšจํ•œ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋Š” ํ•„๋“œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋ฐ ๋ชจ๋ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ํผ์ด ์œ ํšจํ•œ ๊ฒฝ์šฐ, form.save(commit=False)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Todo ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. commit=False๋Š” ์ž„์‹œ๋กœ ์ €์žฅํ•˜๊ณ  ๋‚˜์ค‘์— ๋””๋น„์— ์ €์žฅํ•  ๊ฒƒ์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • todo.save()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ Todo ๊ฐ์ฒด๋ฅผ ๋””๋น„์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • return redirect('todo_list')๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋œ Todo๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํ•  ์ผ ๋ชฉ๋ก ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•ฉ๋‹ˆ๋‹ค.

 

 

3.4.4 Todo ์ƒ์„ฑ URL ์—ฐ๊ฒฐํ•˜๊ธฐ 

์ด์ œ url์„ ์—ฐ๊ฒฐํ•˜๋ฉด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค. 

 

 

 

3.5 Todo ์ˆ˜์ • ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

 

3.5.1 Todo ์ˆ˜์ • ๊ธฐ๋Šฅ ์ปจ์…‰

์ƒ์„ฑ๊ธฐ๋Šฅ๊ณผ ๊ฑฐ์˜ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ๊ณผ์˜ ์ฐจ์ด์ ์€ ํผ์— ์ด๋ฏธ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž…๋ ฅ๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ ๋ฟ

๋”ฐ๋ผ์„œ ์ˆ˜์ • ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค๋•Œ๋Š” ์ƒ์„ฑ ๊ธฐ๋Šฅ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋˜,

๊ธฐ์กด Todo ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™€ ํ•จ๊ป˜ ํƒฌํ”Œ๋ฆฟ์œผ๋กœ ๋ณด๋‚ด๋Š” ๊ฒƒ๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

3.5.2 Todo ์ˆ˜์ • ๋ทฐ ๋งŒ๋“ค๊ธฐ

์ƒ์„ฑ๊ณผ ๋™์ผํ•œ ํ…œํ”Œ๋ฆฟ ์‚ฌ์šฉ, ํผ๋„ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋จ

๋ฐ”๋กœ ๋ทฐ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋˜๋Š”๋ฐ, 

 

๋ทฐ์—์„œ๋Š” ์•ž์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ํผ์— ๊ธฐ์กด Todo ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด์•ผํ•จ

def todo_edit(request, pk):
    todo = Todo.objects.get(id=pk)
    if request.method == "POST":
        form = TodoForm(request.POST, instance=todo)
        if form.is_valid():
            todo = form.save(commit=False)
            todo.save()
            return redirect('todo_list')
    else:
        form = TodoForm(instance=todo)
    return render(request, 'todo/todo_post.html', {'form': form})

 

3.5.3 Todo ์ˆ˜์ • URL ์—ฐ๊ฒฐํ•˜๊ธฐ

 

 

3.6 Todo ์™„๋ฃŒ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

 

3.6.1 Todo ์™„๋ฃŒ ๊ธฐ๋Šฅ ์ปจ์…‰

1. ์™„๋ฃŒ ๋ฒ„ํŠผ ๋ˆŒ๋ €์„ ๋•Œ True๋กœ ์„ค์ •ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ

2. ์™„๋ฃŒ๋œ Todo๋งŒ ํ•„ํ„ฐ๋ง ํ•˜๋ ค ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ธฐ๋Šฅ

 

3.6.2 Todo ์™„๋ฃŒ ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ
<html>
  <head>
    <title>TODO ๋ชฉ๋ก ์•ฑ</title>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
    />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
  </head>
  <body>
  <div class="container">
    <h1>DONE ๋ชฉ๋ก</h1>
    <p>
      <a href="{% url 'todo_list' %}" class="btn btn-primary">ํ™ˆ์œผ๋กœ</a>
    </p>
    <ul class="list-group">
      {% for done in dones %}
      <li class="list-group-item">
        <a href="{% url 'todo_detail' pk=done.pk %}">{{ done.title }}</a>
        {% if done.important %}
          <span class="badge badge-danger">!</span>
        {% endif %}
      </li>
      {% endfor %}
    </ul>
  </body>
  </div>
</html>

 

 

3.6.3 Todo ์™„๋ฃŒ ๋ทฐ ๋งŒ๋“ค๊ธฐ
def done_list(request):
    dones = Todo.objects.filter(complete=True)
    return render(request, 'todo/done_list.html', {'dones': dones})


def todo_done(request, pk):
    todo = Todo.objects.get(id=pk)
    todo.complete = True
    todo.save()
    return redirect('todo_list')

 

 

 

Todo ์™„๋ฃŒ URL ์—ฐ๊ฒฐํ•˜๊ธฐ

๋งˆ์ง€๋ง‰์œผ๋กœ url์„ ์—ฐ๊ฒฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

๊ฐ๊ฐ done/, done// ํ˜•ํƒœ๋กœ ์ง€์ •ํ•ด์ฃผ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

 

https://link.coupang.com/a/UtLyC

 

๋ฐฑ์—”๋“œ๋ฅผ ์œ„ํ•œ Django REST Framework with ํŒŒ์ด์ฌ

COUPANG

www.coupang.com

 

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."