ํ์คํ ์น๐ ๊ฐ๋ฐ์ ์ง๋ง์ ๐ง๐ฝโ๐ป
โ ์ธ๊ณต์ง๋ฅ ๊ด์ฌ ๐ค
Categories
-
โฃ
โถ COMPUTER_SCIENCE
๐: 7 -
โฃ
โถ WEB
๐: 3 -
โฃ
โถ ETC
๐: 3-
โ
โฃ
ETCS
๐: 10 -
โ
โฃ
SUBBRAIN ๊ฐ๋ฐ๊ธฐ
๐: 5 -
โ
โ
YOS ๊ฐ๋ฐ๊ธฐ
๐: 1
-
โ
โฃ
-
โ
โถ AI
๐: 9-
โฃ
AITOOLS
๐: 3 -
โฃ
CV
๐: 2 -
โฃ
DEEP_LEARNING
๐: 1 -
โฃ
DATA_VIS
๐: 2 -
โฃ
GRAPH
๐: 1 -
โฃ
LIGHTWEIGHT
๐: 1 -
โฃ
MATH
๐: 1 -
โฃ
NLP
๐: 3 -
โ
STRUCTURED_DATA
๐: 2
-
โฃ
Django CRUD
- Django ํ๋ก์ ํธ ์์ฑ๊ณผ ๊ฐ์ ํ๊ฒฝ ์ค์
- Django ์ฑ ์์ฑ๊ณผ ์ถ๊ฐ
- ๊ธฐ๋ณธ html ํ์ผ ์ค์
- Django Read(detail) ์์ฑ
- Django Update ์์ฑ
Django CRUD(Create, Read, Update, Delete ) ๋ง๋ค๊ธฐ
Django ํ๋ก์ ํธ ์์ฑ๊ณผ ๊ฐ์ ํ๊ฒฝ ์ค์
- mkdir ๋์ํด๋์ด๋ฆ, cd ๋์ํด๋ ์ด๋ฆ์ผ๋ก ํด๋๋ฅผ ์์ฑํ๊ณ ์ด๋ํ๋ค
- python -m venv venv๋ก ํด๋น ๋๋ ํ ๋ฆฌ์ ํด๋์ด๋ฆ์ ๊ฐ์ํ๊ฒฝ์ ๋ง๋ค์ด์ค
- source venv/Scripts/activate๋ก ํฐ๋ฏธ๋์ ๊ฐ์ํ๊ฒฝ์ ๋ค์ด๊ฐ๊ฒ ํ๋ค. (deactivate๋ก ๋๊ฐ)
- ๋๋ vsCode์์ f1์ผ๋ก select interpreter๋ฅผ ํตํ์ฌ ๊ฐ์ํ๊ฒฝ ๋ค์ด๊ฐ๊ธฐ ๊ฐ๋ฅ
- pip install django๋ก ๊ฐ์ํ๊ฒฝ ๋ด์ django๋ฅผ ์ค์นํ๋ค.
- django-admin startproject ํ๋ก์ ํธ๋ช
. ์ผ๋ก ํ์ฌ ํด๋ ๋ด์ ํ๋ก์ ํธ๋ฅผ ๋ง๋ ๋ค
- ๋ง์ง๋ง .์ด ์์ผ๋ฉด ํ๋ก์ ํธ๋ช ์ผ๋ก ๋ ํด๋๋ฅผ ๋ง๋ค๊ณ ๊ทธ ๋ด๋ถ์ ๋ง๋ค๊ฒ ๋๋ค.
- python manage.py runserver๋ก ์๋ฒ๋ฅผ ๋๋ฆฌ๊ณ ํ์ธํด๋ณธ๋ค.
- http://127.0.0.1:8000/ ๊ฐ ๊ธฐ๋ณธ ์ฃผ์ , ํฐ๋ฏธ๋์์ Ctrl + C๋ก ์๋ฒ๋ฅผ ๋ซ๋๋ค
- ํฐ๋ฏธ๋์ code .์ ์น๋ฉด ํด๋น ๋๋ ํ ๋ฆฌ๋ก VS Code IDE๊ฐ ์ผ์ง(๋ฒ๊ทธ ์์)
Django ์ฑ ์์ฑ๊ณผ ์ถ๊ฐ
- ๋์ ํด๋(๋ณดํต ํ๋ก์ ํธ ํด๋์ ๋์ผ ์์น)์์ django-admin startapp ์ฑ์ด๋ฆ ์ผ๋ก ์ฑ ์์ฑ
- python manage.py startapp ์ฑ์ด๋ฆ ์ผ๋ก๋ ๊ฐ๋ฅ
- ํ๋ก์ ํธ๋ช
ํด๋ ๋ด๋ถ์ settings.py์ INSTALLED_APPS ๋ฆฌ์คํธ์ ์ฑ์ด๋ฆ์ ์ถ๊ฐ
- ๋ณดํต ์ปค์คํ
app์ ๋งจ ์์ ๋์ผ๋ฉฐ ๋๋ช
์ผ์ ๋งจ ์์ app์ด ์ฐ์ ์ด๋ค.(โ,โ ์ถ๊ฐ ์ฃผ์)
myCRUD ํ๋ก์ ํธ ํด๋ ๋ด๋ถ์ settings.py์ ์ผ๋ถ
```python
# Application definition
INSTALLED_APPS = [
'CRUD', # ์ฑ ์ด๋ฆ
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
] - ๋ณดํต ์ปค์คํ
app์ ๋งจ ์์ ๋์ผ๋ฉฐ ๋๋ช
์ผ์ ๋งจ ์์ app์ด ์ฐ์ ์ด๋ค.(โ,โ ์ถ๊ฐ ์ฃผ์)
3. ๋์ผํ ํด๋์ urls.py ํ์ผ ๋ด๋ถ์ urlpatterns ๋ฆฌ์คํธ์ path()ํจ์๋ฅผ ์ด์ฉํด ํด๋น ์ฑ URL ์ถ๊ฐ
- ๋ณดํต path('์ฑ์ด๋ฆ/', include('์ฑ์ด๋ฆ.urls')), ๋ฅผ ์ถ๊ฐํ๋ค (๋ค์ / ์ถ๊ฐ ํ์!)
- ๊ตณ์ด ์ฑ์ด๋ฆ์ ์ธํ์ ์์ง๋ง ๊ด๋ก์ ํจ์จ ์ ๊ทธ๋ ๊ฒ ํ๋ค.
- include()ํจ์๋ django.urls์์ ์ํฌํธ ํด์จ๋ค.(from django.urls import path, include)
> ํ๋ก์ ํธ ํด๋์ urls.py์ ์ผ๋ถ
```python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('CRUD/', include('CRUD.urls')),
]
- ํด๋น ์ฑ ํด๋ ๋ด๋ถ์ urls.py ํ์ผ์ ์์ฑํ๊ณ , urlpatterns ๋ฆฌ์คํธ๋ฅผ ๋ง๋ ๋ค
- ํ์ ๋ชจ๋๋ค (django.urls์ pathํจ์, ํด๋น ํด๋(.)์ views ํ์ผ ๋ฑ)์ ์ํฌํธ
์ฑ ํด๋ ๋ด๋ถ์ ์๋ก๋ง๋ urls.py ์์
```python
from django.urls import path
from . import views
app_name = 'CRUD' # ์ผ๋ฐ์ ์ผ๋ก ์ฑ ์ด๋ฆ๊ณผ ๊ฐ์ ์ด๋ฆ์ ๋ฃ์
urlpatterns = [
path('create/', views.create, name="create"),
# variable routing + namespacing
path('<int:id>/update/', views.update, name="update"),
# ๊ธฐํ ํ์ํ path ์ถ๊ฐ
]
## model์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ ์ถ๊ฐ
1. ํด๋น ์ฑ ํด๋ ๋ด๋ถ์ models.py ํ์ผ์ ์ํ๋ ์ด๋ฆ์ ๋ชจ๋ธ ํด๋์ค๋ฅผ ๋ง๋ ๋ค.
- ์ด ํด๋์ค๋ models.Model์ ์์๋ฐ์์ผํ๋ค.
2. ๋ด๋ถ์ ํด๋์ค ๋ณ์๋ก ๊ฐ๊ฐ์ ์ ๋ณด ํ๋๋ฅผ ์ค์ ํ๋ค.
- models.CharField(max_length=)๋ ๋ณดํต ์งง์ ๋ด์ฉ์ ๋ฌธ์์ด ์ ๋ณด์ ์ฌ์ฉํ๋ฉฐ, max_length๋ผ๋ ์ต๋ ์ ์ฅ ๊ณต๊ฐ์ ๋ฏธ๋ฆฌ ํ ๋นํด์ค์ผ ํ๋ค.
- models.TextFiled()๋ ๋ณดํต ๋ณธ๋ฌธ ๊ฐ์ ๊ธด ๊ธธ์ด์ ๋ฌธ์์ด ์ ๋ณด์ ์ฌ์ฉ, max_length ํ ๋น์ด ํ์ ์๋ค
- models.DateField()๋ ๋ ์ง์ ์๊ฐ ์ ๋ณด์ ์ฌ์ฉํ๋ค.
- models.BooleanField()๋ ์ฐธ, ๊ฑฐ์ง์ผ๋ก ๊ตฌ๋ถํ๋ ์ ๋ณด์ ์ฌ์ฉํ๋ค.
> ํด๋น ์ฑ ํด๋์ models.py ์์
```python
from django.db import models
# Create your models here.
class TODO(models.Model): # models.Model ์์ํด์ฃผ๊ธฐ ํ์
title = models.CharField(max_length=50)
content = models.TextField()
due_date = models.DateField()
check = models.BooleanField()
def __str__(self): # __str__์ ์ค๋ฒ๋ก๋ฉํ๋ฉด admin์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฐ์์ฑ์ข๊ฒ ๋ณด์ฌ์ค ์ ์๋ค.
return f'{self.due_date}๊น์ง {self.title}์ผ์ ํด์ผํฉ๋๋ค. ๋ด์ฉ : {self.content}, ํ๋ ์ฌ๋ถ : {self.check}'
- ํด๋น ๋ฐ์ดํฐํ๋์ ์ข
๋ฅ๋ฅผ ์ ์ค์ ํด์ค์ผ, ๋์ค์ form ์๋ ์์ฑ๊ธฐ๋ฅ์ ์ฌ์ฉํ ๋ ์ ์ ํ๊ฒ ์์ฑ๋๋ค.
- ๋ชจ๋ธ์ด ์์ฑ๋๋ฉด ํฐ๋ฏธ๋์์ python manage.py makemigrations๋ฅผ ํตํ์ฌ ๋ชจ๋ธ์ SQL ๋ฒ์ญ๊ธฐ๋ก ๋ณด๋ธ๋ค. (์ผ์ข ์ ๋ฐ์ดํฐํ ํค๋ ๋ง๋ค๊ธฐ)
- ์ด๋ 0001_initial.py๊ฐ ์์ฑ๋๋ฉฐ, ์ง์ฐ๋ฉด ๋ค์ ๋ง๋ค์ด์ค์ผ ํ๋ค.
- python manage.py migrate๋ฅผ ํตํด SQL๋ก ํด์ํ๋ค. (์ผ์ข ์ ๋ฐ์ดํฐ ํ ๊ทธ๋ฆฌ๊ธฐ)
- ์ด๋ ๋ชจ๋ธ๋ง์ ์ ์คํํ์ฌ ๋์ค์ ๋ชจ๋ธ์ ์์ ํ๋ ์ผ์ ์๋๋ก ํ์.
- ๋ชจ๋ธ๋ง ์์ ์ ํด๋น ๋ชจ๋ธ ํ์ผ(0001_initial.py)๋ฅผ ์ง์ฐ๊ณ ๋ค์ ๋ง๋ค์ด์ผ ํ๋ค.
- ๋ง์ฝ ๊ธฐ์กด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํด๋น ๋ชจ๋ธ์ ์ ๋ณด๊ฐ ์์ผ๋ฉด ๋ฌธ์ ๋ฅผ ์ผ์ผํจ๋ค. (๋ค ์ง์ฐ๊ณ ์๋ก ๋ฐ๊ฟ์ฃผ๋๊ฒ ๋์)
๊ธฐ๋ณธ html ํ์ผ ์ค์
- ํด๋น ์ฑ ํด๋ ๋ด๋ถ์ templates ๋ผ๋ ์ด๋ฆ์ผ๋ก ์ ํด๋๋ฅผ ๋ง๋ ๋ค.
- ๋ด๋ถ ํด๋์ base.html์ ๋ง๋ค๊ณ !+tab์ผ๋ก ๊ธฐ๋ณธ ํ์์ ์ก๋๋ค.
- <body>ํ๊ทธ ์ฌ์ด์ {% block body %}์ {% endblock %} DTL ๋ฌธ๋ฒ์ ๋ฃ๋๋ค.
- ์ด๋ ์ํ๋ค๋ฉด bootstrap์ ์ถ๊ฐํ๊ฑฐ๋ ์ฌ๋ฌ๊ฐ์ง๋ฅผ ๊พธ๋ฏผ๋ค.
base.html ํ์ผ ์์
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MyOwnSuckyBulletin</title>
</head>
<body>
{% block body %}
{% endblock %}
{% block body2 %}
{% endblock %}
<!โ์ด๋ฐ ์์ผ๋ก 2๊ฐ ์ด์ ๋์ ์๋ ์๋ค.โ>
<!โhtml ์ฃผ์ ๋ฌ๊ธฐ, ํ์ง๋ง DTL๊ณผ ์ถฉ๋์ด ์ผ์ด๋ ์ ๋ ์๋ค. โ>
</body>
</html>
4. base.html๊ณผ ๊ฐ์ ํด๋์ index.html ํ์ผ์ ๋ง๋ค์ด์ค๋ค.
5. {% extends 'base.html' %}, {% block body %}, {% endblock %}๋ฅผ ํตํ์ฌ base.html์ ํ
ํ๋ฆฟ์ ๊ฐ์ ธ์จ๋ค.
- body๋ผ๋ ์ด๋ฆ์ ๋ฐ๊พธ๋ฉด ๋ค๋ฅธ ์์น์ ํ
ํ๋ฆฟ์ ๊ฐ์ ธ์ฌ ์ ์๋ค.
- ํ์ง๋ง 2๊ฐ์ด์์ ํ
ํ๋ฆฟ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ํ ์ ์๋ค.
6. ํด๋น ํด๋์ urls.py์ urlpatterns์ ๋ฉ์ธ ํ์ด์ง ํ์๋ฅผ ์ํ path๋ฅผ ์ถ๊ฐํ๋ค.
7. ํด๋น ํด๋์ views.py์ index ํจ์๋ฅผ ๋ง๋ค๊ณ ์ถ๊ฐํ ๋ชจ๋ธ๋ค์ ์ ๋ ฌ ํ ๋ณ์์ ์ง์ด๋ฃ๋๋ค.
8. index ํจ์๋ก index.html ํ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ฃผ๊ณ ์ถ๋ ฅํ๋ html ์ฝ๋๋ฅผ ๋ง๋ ๋ค.
> urls.py์ ์ผ๋ถ(์ฑ ๋ด๋ถ ํด๋)
```python
urlpatterns = [
path('', views.index, name="index"), #todos์ ๋ฉ์ธ ํ์ด์ง url์ ์๋ฏธ
]
views.py (์ฑ ๋ด๋ถ ํด๋)
```python
from django.shortcuts import render
from .models import TODO์ด์ฉํ ๋ชจ๋ธ์ models.py์์ ๊ฐ์ ธ์์ผ ํ๋ค.
Create your views here.
def index(request): # request๋ ์์ฒญ์๊ฐ ๋ณด๋ธ ์ ๋ณด๋ค์ด ๋ด๊ฒจ์ ธ์๋ค.
todos = TODO.objects.order_by('due_date').all() # ๋ ์ง์์ผ๋ก ์ ๋ ฌ
context = { # context๋ผ๋ ๋์ ๋๋ฆฌ ํํ๋ก ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค.
'todos': todos,
}
return render(request, 'index.html', context)render ํจ์๋ ์ ๋ณด์ html ์ฝ๋, ๊ฐ๊ณต๋ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์ฌ๋๋ค์๊ฒ ๋ณด์ฌ์ค ํ์ด์ง๋ฅผ ๋ง๋ค์ด์ค๋ค.
- ๋ชจ๋ธ ํด๋์ค ๋ด๋ถ์ ํจ์๋ค
- ๋ชจ๋ธ.objects.all(count) : ํด๋์ค์ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ์ถ๋ ฅ, count๋ฅผ ๋น์นธ์ผ๋ก ๋์ง ์์ผ๋ฉด, count๋ฒ์งธ ์์๋ฅผ ๊ฐ์ ธ์จ๋ค.
- ๋ชจ๋ธ.objects.get(id=count, title="content"): 1๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ง ๊ฐ์ ธ์จ๋ค. id์ ๊ฐ์ ์ง์ ํ๋ฉด, id๊ฐ 1์ธ ๊ฐ์ฒด ํ๋, content๋ฅผ ์ง์ ํ๋ฉด ํด๋น content๋ฅผ title๋ก ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์จ๋ค. ์ผ์นํ๋ ๊ฐ์ฒด๊ฐ 2๊ฐ ์ด์ ์์ผ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
- ๋ชจ๋ธ.objects.filter(title="hello") : ๊ดํธ์์ ์กฐ๊ฑด๊ณผ ์ผ์นํ๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด ex) title="hello", ์ธ ๋ชจ๋ ๊ฐ์ฒด ๊ฐ์ ธ์ด
- ๋ชจ๋ธ ๊ฐ์ฒด.delete() : ํด๋น ๋ชจ๋ธ ๊ฐ์ฒด ์ญ์
- ๋ชจ๋ธ๊ฐ์ฒด = ๋ชจ๋ธ์ด๋ฆ(์ด์์=๋ด์ฉ,์ด์์2=๋ด์ฉ2) : ๋ชจ๋ธ ๊ฐ์ฒด ์์ฑ
- > ๋ชจ๋ธ ๊ฐ์ฒด ์์ฑ 2
- ```python
๋ชจ๋ธ๊ฐ์ฒด = ๋ชจ๋ธ์ด๋ฆ()
๋ชจ๋ธ๊ฐ์ฒด.์ด์์1 = ๋ด์ฉ
๋ชจ๋ธ๊ฒ์ฒด.์ด์์2 = ๋ด์ฉ
๋ชจ๋ธ๊ฐ์ฒด.save() # ๋ชจ๋ธ ๊ฐ์ฒด ์ ์ฉ
- ์ด ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋ธ๊ฐ์ฒด ์์ฑ์ ๋ค๋ฅธ ํ์ด๋ฐ์ ํ ์ ์๋ค. > index.html (์ฑ ๋ด๋ถ templates ํด๋ ๋ด๋ถ) ```html {% extends 'base.html' %} &#60;!--base.html์ ํ
ํ๋ฆฟ์ ๊ฐ์ ธ์ด--&#62; {% block body %} &#60;!-- base.html์ ๊ตฌ๋ฉ์ ์ ํ--&#62;
{% for todo in todos %} &#60;!-- DTL for๋ฌธ ๊ตฌ๋ฌธ--&#62;
์ ๋ชฉ : &#60;h1&#62;todo.title&#60;/h1&#62; &#60;!-- ๊ฐ todo ๊ฐ์ฒด์ ๋ด์ฉ๋ฌผ ๋ณด์ฌ์ฃผ๊ธฐ--&#62;
๋ด์ฉ : &#60;h2&#62;todo.content&#60;/h2&#62;
๋ ์ง : &#60;h3&#62;todo.due_date&#60;/h3&#62;
์ฒดํฌ : &#60;h3&#62;todo.check&#60;/h3&#62;
{% endfor %}&#60;!-- for๋ฌธ, ๊ผญ ๋์ ์๋ฆด๊ฒ --&#62; {% endblock %} &#60;!-- block์ ๋ --&#62;
## Django Create ์์ฑ
1. ์ฑ์ urls.py์ urlpatterns ๋ฆฌ์คํธ์ url์ด๋ฆ, views์ ํจ์, url ๋ณ์๋ช
์ ํ ๋นํด ๋ฃ๋๋ค.
> ์ฑ ํด๋ ๋ด๋ถ์ urls.py์ urlpatterns ์์
```python
urlpatterns = [
path('create/', views.create, name="create"),
#๋ค์ name์ namespacing์ผ๋ก, url๋์ ์ธ ์ด๋ฆ
# ๊ธฐํ ํ์ํ path ์ถ๊ฐ
]
- ํด๋น ์ฑ ํด๋ ๋ด๋ถ์ views.py ํ์ผ๋ก ๊ฐ์ ์ pathํจ์์ 2๋ฒ์งธ ์ธ์์ธ ํจ์๋ช
์ ๋ง๋ ๋ค. (์ผ๋ฐ์ ์ผ๋ก url ์ด๋ฆ๊ณผ ๊ฐ๋ค.)
์ฑ ํด๋ ๋ด๋ถ์ views.py์ create ํจ์ ์์
```python
from django.shortcuts import render, redirect # redirect์ render๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ํฌํธ ํด์ผํ๋ค.
from .models import TODO # ์ฌ์ฉํ ๋ชจ๋ธ ๋ํ ๋ถ๋ฌ์์ผํจ
def create(request):
if request.method == "POST": # ๋ง์ฝ form์ method๊ฐ Post์ธ์ฑ๋ก ๋ณด๋ด์ง๋ฉด?
# ๊ทธ๋ ๋ค๋ฉด ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ๋ฆฌ๊ณ ๋ฉ์ธ ํ์ด์ง๋ก ๋๋ ค๋ณด๋
check = request.POST.get('check') # check ๋๋ฉด 'on'์ ๋ฆฌํดํจ
if check == 'on':
check = True
else:
check = False
title = request.POST.get('title')
content = request.POST.get('content')
due_date = request.POST.get('due-date')
# todo = TODO()
# todo.check = check
# todo.title = title
# todo.content = content
# todo.due_date = due_date
# todo.save() # ๋๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ ์ฝ๋
# ๋ ๊ธธ์ง๋ง ๋์ save()๋ฅผ ์ด์ฉํด todo ๊ฐ์ฒด์ ์์ฑ ํ์ด๋ฐ์ ์ํ๋ ์๊ฐ์ ํ ์ ์์
todo = TODO.objects.create(check=check, title=title, content=content, due_date=due_date)
return redirect('CRUD:index') # /์์ผ๋ฉด ๋ฃจํธ์ฃผ์์ ์ถ๊ฐ, ์์ผ๋ฉด ํ์ฌ ์ฃผ์ ์์ ์ถ๊ฐ
else: # form์ method๊ฐ Get์ด๋ผ๋ฉด?
# ๊ทธ๋ ๋ค๋ฉด todo ์ ๋ณด๋ฅผ ์
๋ ฅํ๋ ํ์ด์ง๋ก ๋ณด๋ด์ผํจ
return render(request, 'create.html')
- ๊ธฐ๋ณธ ์ ๋ณด method๋ GET๋ฐฉ์์ด๋ค. ์ฌ์ฉ์๊ฐ ์๋ก์ด ๊ธ์ ์ฐ๊ธฐ ์ํด create url๋ก ๋ค์ด์ค๋ฉด GET๋ฐฉ์์ด๋ฏ๋ก crete.html์ด ๋ง๋๋ ํ์ด์ง๋ก ๊ฐ์ ์ ๋ณด ์
๋ ฅ์ฐฝ์ผ๋ก ๊ฐ๋ค.
- ์ ๋ณด๋ฅผ ๋ชจ๋ ์
๋ ฅํ๊ณ ์ฌ์ฉ์๊ฐ method๋ฅผ POST ๋ฐฉ์์ผ๋ก ์ค์ ํ ํผ์์ submit ๋ฒํผ์ ๋๋ฅด๋ฉด, POST ๋ฐฉ์์ผ๋ก ์ ๋ณด๊ฐ ๋ค์ด์ค๋ฏ๋ก TODO ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ ๋ฉ์ธํ์ด์ง๋ก ๋์๊ฐ๋ค.
- ์ด๋ฐ ์์ผ๋ก ํ๋์ url ์ฃผ์์์ ๋ฐ์ ์ ๋ณด ์ ํ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋์ํ๊ฒ ๋ง๋ค์ด ํจ์จ์ ์ธ ์น ์ฝ๋ฉ์ ๊ตฌํํ ๊ฒ์ด restfullํ ์น ์ฝ๋ฉ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
- ๋ค๋ฅธ ํ๋ ์์ํฌ๋ delete์ put ํ์์ method๋ ์ง์ํ๋ django์ HTML5๋ ๊ณต์์ ์ผ๋ก ์ง์ํ์ง ์๊ณ ์๋ค. ์ด์ธ์ ์ธ๊ธฐ์๋ http verb ๋ผ๋ ๊ฐ๋
๋ ์ง์์ํจ
- HTML5๋ ๊ณต์์ ์ผ๋ก ์ง์ํ์ง ์์ผ๋ฏ๋ก delete์ putํ์์ผ๋ก ๋ณด๋ผ ๋๋ ์๋ก input ํ๊ทธ๋ฅผ ๋ง๋ค์ด, type= hidden์ name='_method', value="DELETE" ๋ก ์จ๊ฒจ์ ๋ณด๋
3. templates ํด๋์ create.html์ ๋ง๋ ๋ค.
> create.html ์์
```html
{% extends 'base.html' %}
{% block body %}
&#60;form action="{% url 'CRUD:create' %}" method="POST"&#62; # ๋์๋ฌธ์ ๊ตฌ๋ณ์ํจ
{% csrf_token %} # ํผ ๋ด๋ถ์ ์ด๊ฒ ์์ด์ผ์ง ์ธ์ฆ์ด๋์ ์๋ฌ ์๋จ
๋ฌ์ฑ์ฌ๋ถ : &#60;input type="checkbox" name="check"&#62; # checkํ๋ฉด 'on'์ ๋ณด๋
์ ๋ชฉ : &#60;input type="text" name="title"&#62; # ๊ฐ์ ๋ชจ๋ธ ์ ๋ณด๋ช
์ผ๋ก ๋ณด๋
๋ด์ฉ : &#60;input type="text" name="content"&#62;
๋ง๊ฐ์ผ : &#60;input type="date" name="due-date"&#62;
&#60;input type="submit" value="์ ์ฅ"&#62;
&#60;/form&#62;
{% endblock %}
- form์ action ์์๋ฅผ DTL ๋ฌธ๋ฒ์ผ๋ก namespacing์ ์ด์ฉํ์ฌ ๋ณด๋ผ ์ ์๋ค.
- โ{% url โ์ฑ์ด๋ฆ:url๋ณ์๋ช โ ๋งค๊ฐ๋ณ์1, ๋งค๊ฐ๋ณ์2, โฆ%}โ ๋งค๊ฐ๋ณ์ ๋ํ ๋ณด๋ผ ์ ์์ผ๋ฉฐ, ์ฑ์ด๋ฆ์ ์ค์ ํ์ง ์์ผ๋ฉด โ์ฑ์ด๋ฆ:โ๋ถ๋ถ์ ๋นผ๋ ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ค๋ฅธ ์ฑ์ ๊ฒน์น๋ url ๋ณ์๋ช ์ด ์๋ก ์ถฉ๋ํ ์ ์๋ค.
- POST ๋ฐฉ์์ผ๋ก ๋ณด๋ด๋ฉด url ์ฃผ์์ ์ ๋ณด ๊ฐ์ด ๋ณด์ด์ง ์๊ณ , csrf๋ก ์ํธํ๋์ ๋ณด๋ด์ง๋ฉฐ, ์ด๋ฅผ ์ ๋๋ก ํด๋
ํด์ ๋ฐ์ผ๋ ค๋ฉด form ํ๊ทธ ๋ด๋ถ์ {% csrf_token %}์ ์ง์ ํ์ฌ ํ ํฐ๋ ๊ฐ์ด ๋ณด๋ด์ผ ํ๋ค. ์ด๋ฅผ ํตํด restfull ํ ์น ์ฝ๋ฉ๋ ๊ฐ๋ฅํ๋ค.
Django Read(detail) ์์ฑ
- ๋จผ์ ์ฑ ํด๋ ๋ด๋ถ์ urlpatterns ๋ฆฌ์คํธ์ ์๋ก path๋ฅผ ์ถ๊ฐํ๋ค.
์๋ก ์ถ๊ฐํ detail path
```python
path('<int:id>/', views.detail, name="detail"), # ์์ธํ ๋ณผ id๋ฅผ variable routing ํด์ผํจ
- ๋จผ์ ์ฑ ํด๋ ๋ด๋ถ์ urlpatterns ๋ฆฌ์คํธ์ ์๋ก path๋ฅผ ์ถ๊ฐํ๋ค.
2. views.py์ detail ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
> ์๋ก ์ถ๊ฐํ detail ํจ์
```python
def detail(request, id): #์์ธํ ๋ณผ todo์ id๋ฅผ htmlํ์ผ๋ก ๋๊ฒจ์ฃผ์ด์ผ ํ๋ค.
todo = TODO.objects.get(id=id) # ํด๋น id์ธ TODO ๊ฐ์ฒด ์ฐพ๊ธฐ
context = { # render๋ก ๋๊ฒจ์ค ๋ 3๋ฒ์งธ ์ธ์๋ก, ๋์
๋๋ฆฌ ํํ๋ก ๋๊ฒจ์ค์ผํ๋ค.
'todo': todo,
}
return render(request, 'detail.html', context)
- deatil.html ํ์ผ์ ๋ง๋ค์ด templates ํด๋์ ์ถ๊ฐํ๋ค.
detail.html
```python
{% extends 'base.html' %}
{% block body %}
<h1>{{todo.title}}</h1>
<h2>{{todo.content}}</h2>
<h3>{{todo.due_date}}</h3>
<h3>{{todo.check}}</h3>
<a href="">์ญ์ </a>
<a href="">์์ </a>
<a href="{% url 'CRUD:index' %}">๋ค๋ก</a>
{% endblock %}
- ๋ฉ์ธ ํ์ด์ง๋ก ๋์๊ฐ๋๋ ๋ค๋ก์ ๋์ค์ ์ถ๊ฐ๋ ์ญ์ ์ ์์ ๋ฒํผ์ ๋ฃ์๋ค.
4. ๊ธฐ์กด์ ์๋ index.html์ ํด๋น ๋ชจ๋ธ ๊ฐ์ฒด์ detail ํ์ด์ง๋ก ๊ฐ ์ ์๋ ๋งํฌ๋ฅผ ์ถ๊ฐํ๋ค.
> index.html ์ ์ผ๋ถ
```html
&#60;a href="{% url 'CRUD:detail' todo.id %}"&#62;์์ธํ&#60;/a&#62;
- namspacing์ ์ด์ฉํ url ํ ๋น์ todo์ id๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ณด๋ด๊ณ ์๋ค.
- ๋ณด๋ด์ผ๋ ๋ณ์๊ฐ 2๊ฐ ์ด์์ด๋ฉด ์์์ ๋ถํฐ ์ฐจ๋ก๋๋ก ์ ์ฉ.
Django Update ์์ฑ
- ์ฑ ํด๋ ๋ด๋ถ์ urls.py์ urlpatterns ๋ฆฌ์คํธ์ update path๋ฅผ ์ถ๊ฐํ๋ค.
url.py์ ์ผ๋ถ
```python
path('<int:id>/update/', views.update, name="update"),
- ์ฑ ํด๋ ๋ด๋ถ์ urls.py์ urlpatterns ๋ฆฌ์คํธ์ update path๋ฅผ ์ถ๊ฐํ๋ค.
2. ์ฑ ํด๋ ๋ด๋ถ์ views.py์ update ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
> views.py์ update ํจ์
```python
def update(request, id):
todo = TODO.objects.get(id=id) # get์ผ ๋๋, post์ผ ๋๋ todo๋ฅผ ์ฐ๋ฏ๋ก ์ธ๋ถ์์ ๊ตฌํ๋ค.
if request.method == "POST":
todo.check = request.POST.get('check')
if todo.check == 'on':
todo.check = True
else:
todo.check = False
todo.title = request.POST.get('title')
todo.content = request.POST.get('content')
todo.due_date = request.POST.get('due-date')
return redirect('CRUD:index') # ๊ฐ์ ์์ ํ๊ณ ๋ฉ์ธ ํ์ด์ง๋ก
else:
context = {
"todo": todo,
}
return render(request, 'update.html', context)
- update.html ํ์ผ์ templates ํด๋ ์์ ์ถ๊ฐํ๋ค.
update.html
```html
{% extends 'base.html' %}
{% block body %}
<form action="{% url 'CRUD:update' %}" method="POST">
{% csrf_token %}
๋ฌ์ฑ์ฌ๋ถ : <input type="checkbox" name="check">
์ ๋ชฉ : <input type="text" name="title" value="{{todo.title}}">
๋ด์ฉ : <input type="text" name="content" value="{{todo.content}}">
๋ง๊ฐ์ผ : <input type="date" name="due-date" value="{{todo.due_date}}">
<input type="submit" value="์ ์ฅ">
</form>
{% endblock %}
## Django Delete ์์ฑ
## bootstrap ๊พธ๋ฏธ๊ธฐ
## git
1. gitignore.io์ ๊ฐ์ ์์ ์ ํ๊ฒฝ์ ์
๋ ฅํ ๋ค ๊นํ์ ์ฌ๋ฆฌ์ง ์์ ์ค์ ์ ๋ฐ์ .gitignore์ ๋ฃ๊ธฐ
2. github์ ๊ฐ์ ์๋ก์ด ๋ ํฌ์งํ ๋ฆฌ ๋ง๋ค๊ธฐ
3. ํด๋น ํด๋์ ๊ฐ์ ํฐ๋ฏธ๋ ์์ git init์ผ๋ก git ํ๊ฒฝ์ผ๋ก ๋ง๋ ๋ค,
4. ํฐ๋ฏธ๋์ git commit -m "message"๋ก ์ฒซ ์ปค๋ฐ ๋จ๊ธฐ๊ธฐ
5. ํฐ๋ฏธ๋์ git remote add origin ๋ ํฌ์งํ ๋ฆฌ์ฃผ์๋ก ์ฐ๊ฒฐํ๊ธฐ
6. git push origin master๋ก ํ์ฌ ์ํ ์
๋ก๋ํ๊ธฐ
7. git add ., git commit -m "message", git push origin master๋ก ์
๋ฐ์ดํธ, ์ปค๋ฐ ๋จ๊ธฐ๊ธฐ
## admin ์์ฑํ๊ธฐ, ๋ก๊ทธ์ธ ํ๊ธฐ
1. ํฐ๋ฏธ๋์ python manage.py createsuperuser ์
๋ ฅ
2. ํฐ๋ฏธ๋์ ์ ์ ๋ค์, ์ด๋ฉ์ผ์ฃผ์, ํจ์ค์๋ ์
๋ ฅ, ํจ์ค์๋ ํ์ธ์ ๋ฌผ์ด๋ด
- ํจ์ค์๋ ์
๋ ฅ์ ์
๋ ฅ๊ฒฐ๊ณผ๊ฐ ๋์ ๋ณด์ด์ง ์๋๋ค.
2. http://์๋ฒ์ฃผ์/admin ์ ๋ค์ด๊ฐ์ ๋ก๊ทธ์ธํ๋ฉด ๊ด๋ฆฌ์ ํ์ด์ง๋ก ๋ค์ด๊ฐ ์ ์๋ค.
3. ํด๋น ์ฑ ํด๋ ๋ด๋ถ์ admin.py์์ admin.site.register(๋์ ๋ชจ๋ธ)๋ก ๋์ ๋ชจ๋ธ์ ์
๋ฐ์ดํธํ๋ฉด ๊ด๋ฆฌ ํ์ด์ง๋ก ๋ค์ด๊ฐ๋ฉด ๋ณผ ์ ์๋ค.
- ๊ทธ ์ ์ from .models import ๋ชจ๋ธ์ด๋ฆ ์ผ๋ก ๋ถ๋ฌ์จ๋ค.
## ๋๊ธ ๋ฌ๊ธฐ ๊ธฐ๋ฅ
### django ORM
#### READ
> ๊ฒ์๋ฌผ ๊ฐ์ ธ์ค๋ ๋ฒ
```python
Question.objects.get(id=1)
- ์๋ id๋ฉด ์๋ฌ ๋ฐ์
๊ฒ์๋ฌผ ๋ถ๋ฌ์ค๊ธฐ
```python
In [6]: question = Question.objects.get(id=1)
In [7]: question
Out[7]: <Question: Question object (1)>
- ๊ฒ์๋ฌผ ๋ถ๋ฌ์ค๊ธฐ
> ๋๊ธ ์ ์ฅํ๊ธฐ
```python
In [7]: question
Out[7]: &#60;Question: Question object (1)&#62;
In [8]: Answer
Out[8]: questions.models.Answer
In [9]: answer = Answer()
In [10]: answer
Out[10]: &#60;Answer: Answer object (None)&#62; # ์์ง ์ ๋ณด๊ฐ ์์ผ๋ฏ๋ก None
In [11]: answer.content
Out[11]: ''
In [12]: answer.content = "์ด๊ฒ์ ๋๊ธ์
๋๋ค."
In [13]: answer.content
Out[13]: '์ด๊ฒ์ ๋๊ธ์
๋๋ค.'
In [14]: answer.question = question
In [15]: answer.question
Out[15]: &#60;Question: Question object (1)&#62;
In [16]: answer.save() # ์ ๋ณด ๋ค ์์ฑ์ด์ฑ๋ก ํ๋ฉด ์๋ฌ ๋ฐ์
In [17]: answer
Out[17]: &#60;Answer: Answer object (1)&#62;
In [18]: Answer.objects.create(content="๋๋ฒ์งธ ๋๊ธ", question=question)
Out[18]: &#60;Answer: Answer object (2)&#62;
๋๊ธ ์ ๋ณด
In [19]: answer.id
Out[19]: 1
In [20]: answer.pk
Out[20]: 1
In [21]: answer.question_id # answer๊ฐ ๊ฐ์ง๊ณ ์๋ id๊ฐ, **์ด๊ฒ ๋ ๋น ๋ฆ**
Out[21]: 1
In [23]: answer.question.id # answer๊ฐ ๊ฐ์ง๊ณ ์๋ question์ด ๊ฐ์ง๊ณ ์๋ id๊ฐ
Out[23]: 1
- answer.id == answer.pk(primary key) ์์ด๋๋ ๊ฐ์
- question_id์ answer.question.id ๊ฐ์ ๊ฐ์ง๋ง ์ ๊ทผํ๋๋ฐ question์ ์ฐพ์ง ์์ผ๋ฏ๋ก question_id๊ฐ ๋์ฑ ๋น ๋ฅด๋ค.
```python
In [26]: answer.question.content
Out[26]: 'worst mankind on the planet earth'
In [27]: question.answer_set # foreignkey๋ฅผ ๊ฐ์ง๊ณ ์๋ answer์ ์ํด ์๋์ผ๋ก ์์ฑ๋ question์ ์์
Out[27]: <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager at 0x28b04474808>
In [28]: question.answer_set.all()
Out[28]: <QuerySet [<Answer: Answer object (1)>, <Answer: Answer object (2)>]> # answer ๊ฐ์ฒด๊ฐ 2๊ฐ ๋ค์ด์๊ณ ์ด์ ์ ๊ทผ ๊ฐ๋ฅ
- answer๊ฐ ๊ฐ์ง๊ณ ์๋ question์ ๋ด์ฉ์ ์ ๊ทผ ๊ฐ๋ฅ
#### 1:N
> Question(1)=>Answer(N) : answer_set ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅ
```python
In [28]: question.answer_set.all()
Out[28]: &#60;QuerySet [&#60;Answer: Answer object (1)&#62;, &#60;Answer: Answer object (2)&#62;]&#62;
- question.answer ๋ก๋ ๊ฐ์ ธ์ฌ ์ ์๋ค. (1๊ฐ์ฌ๋)
- ํญ์ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ฌ๊ฐ๋ผ๊ณ ์๊ฐํด์ผํ๋ค.
- question์๋ answer์ ๋ํ ์ ๋ณด๋ฅผ ๋ฃ์ง ์๋๋ค.(์์ ์๋ ์์ผ๋ฏ๋ก) dir(๊ฐ์ฒด)๋ก ํ์ธ ๊ฐ๋ฅ
Answer(N)=>Question(1): question ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅ
```python
In [15]: answer.question
Out[15]: <Question: Question object (1)>
```
_articles/web/backend/Django/Django CRUD.md