์ฅ๊ณ (Django) - ํ์๊ฐ์ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ (MVC)
- -
*๋น๋ฐ๋ฒํธ๋๊ณผ ๋น๋ฐ๋ฒํธ ํ์ธ ๋์ ๋ค๋ฅด๊ฒ ์ ๋ ฅํ์๋
*์๋ฌด๊ฒ๋ ์ ๋ ฅํ์ง ์๊ณ ๋ฑ๋ก ํ์๋
*Admin์์ ๋ฑ๋ก๋ ๋ชฉ๋ก
์ด์ ํฌ์คํ ์์ ์์ฑํ๋ user๋ผ๋ app์ ํ์๊ฐ์ ์ ์ํ ๋ฐ์ดํฐ ์ ์ก ๋ฐ ์ฝ์ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
1. ์ฅ๊ณ ORM์ ์ฌ์ฉํ์ฌ DB ํ ์ด๋ธ ๋ง๋ค๊ธฐ
ํ์๊ฐ์ ์์์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฐ(name, password)๋ฅผ DB์ ์ ์ฅํ๊ธฐ ์ํ models.py ์ ๋๋ค.
*userํด๋ - models.py
from django.db import models
# Create your models here.
class User(models.Model): #์ฅ๊ณ ์์ ์ ๊ณตํ๋ models.Model๋ฅผ ์์๋ฐ์์ผํ๋ค.
username = models.CharField(max_length=64,verbose_name = '์ฌ์ฉ์๋ช
')
password = models.CharField(max_length=64,verbose_name = '๋น๋ฐ๋ฒํธ')
registered_dttm = models.DateTimeField(auto_now_add=True,verbose_name='๋ฑ๋ก์๊ฐ')
#์ ์ฅ๋๋ ์์ ์ ์๊ฐ์ ์๋์ผ๋ก ์ฝ์
ํด์ค๋ค.
class Meta: #๋ฉํ ํด๋์ค๋ฅผ ์ด์ฉํ์ฌ ํ
์ด๋ธ๋ช
์ง์
db_table = 'test_user'
ํด๋์ค๋ฅผ ์์ฑํ๊ณ , models.Model์ ์์๋ฐ์์ผ ํฉ๋๋ค. (์ฅ๊ณ ORM์ ์ฌ์ฉํ๊ธฐ ์ํจ์ ๋๋ค.)
ORM : SQL์ฟผ๋ฆฌ๋ฌธ์ ์ฌ์ฉํ์ง ์๊ณ , ์ฅ๊ณ ๋ชจ๋ธ์ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ
models.CharField : ๋ฌธ์๋ฅผ ๋ฃ์ ํ๋๋ฅผ ์์ฑํฉ๋๋ค. max_length ์ต์ ์ผ๋ก ๊ธธ์ด๋ฅผ ์ ํํฉ๋๋ค. (์ ํ๊ธธ์ด ์์ด ๊ธด ๋ฌธ์์ด ex)๊ฒ์๊ธ ๊ฐ์ ๊ฒฝ์ฐ๋ models.TextField ๋ฅผ ์ฌ์ฉํฉ๋๋ค.)
models.DateTimeField - auto_now_add : ํ์ฌ์๊ฐ ์ฝ์ ์ต์ (USE๋ผ๋ ํ์ค์๊ฐ์ด ์ฝ์ ๋ฉ๋๋ค. ํ๊ตญ์๊ฐ์ ์ฝ์ ํ๋ ค๋ฉด Time_zone์ ๋ฐ๊พธ๋ฉด ๋ฉ๋๋ค )
verbose_name : ๋์ค์ admin(๊ด๋ฆฌ์)ํ์ด์ง์์ ๋ณด์ฌ์ง๋ ์ด๋ฆ์ ๋๋ค. (์์๋ณด๊ธฐ ์ฌ์ด ์ค๋ช ์ ์ฐ๋ฉด ๋ฉ๋๋ค.)
Meta (class): ์์ฑํ ๋ชจ๋ธํด๋์ค์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ๋ ํด๋์ค์ ๋๋ค. ์ ์ฝ๋์์๋ ํ ์ด๋ธ ์ด๋ฆ์ ์ถ๊ฐํ์ต๋๋ค.
Meta (class) - db_table : ํ ์ด๋ธ ์ด๋ฆ์ ์ค์ ํฉ๋๋ค. ๋ง์ฝ ์ค์ ํ์ง ์๋๋ค๋ฉด ์๋์ผ๋ก ํด๋์ค๋ช + app์ด๋ฆ ๊ณผ ๊ฐ์ ํ์์ผ๋ก ์ด๋ฆ์ด ์ค์ ๋ฉ๋๋ค.
Time_zone ์ ํ (Asia/seoul ์๊ฐ)
*setting.py
TIME_ZONE = 'Asia/Seoul' # timezone1์์ธ
USE_I18N = True
USE_L10N = True
USE_TZ = False
2. ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ ์์ฑ (make migrations)
ํฐ๋ฏธ๋์ ์
๋ ฅ
python manage.py makemigrations
ํฐ๋ฏธ๋์ฐฝ์ python manage.py makemigrations ์ ์ ๋ ฅํด์ค๋๋ค. ์ ๋ ฅํ๊ฒ ๋๋ฉด, userํด๋ ํ์์ migrations ๋ผ๋ ํด๋๊ฐ ์์ฑ๋๋ฉฐ, 0001_initial.py๋ผ๋ ํ์ผ์ด ์์ฑ๋ฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ ,์ด์๊ณผ ๊ฐ์ต๋๋ค.
(์ด๋ 0001์ ์ซ์๋ ์๋ฒ์ด๋ฉฐ, ์ถํ ํ์ผ์์ ํ ๋ค์ ๋ชจ๋ธ์ ์ฌ์์ฑํ๋ฉด 0002๋ก ์์ฑ๋ฉ๋๋ค. )
์ ์์ ์ผ๋ก ์ ๋ ฅํ๋ค๋ฉด ๋ค์ ๋ฉ์์ง์ฐฝ์ด ๋น๋๋ค.
3.๋ง์ด๊ทธ๋ ์ด์ DB์ ๋ฐ์ํ๊ธฐ (migrate)
ํฐ๋ฏธ๋์ ์
๋ ฅ
python manage.py migrate
์๊น ๋ง๋ค์๋ ํด๋์ค์ ์ฌ๋ฌ๊ฐ์ง ์ต์ ๋ค์ ์ ์ฉํด์ค๋๋ค. (๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ์ ์์ฑํฉ๋๋ค.)
ํ๋ก์ ํธ์ setting.py๋ฅผ ๋ณด์๋ฉด DATABASE๋ sqlite3์ผ๋ก ์ค์ ๋์ด์์ต๋๋ค.(์ด๊ธฐ์ค์ )
๋ฐ๋ผ์ ์์ migrate๋ฅผ ์คํํ๊ฒ๋๋ฉด sqlite3์ผ๋ก ํ์ผ์ด ์์ฑ๋ฉ๋๋ค.
์ฆ, DB๊ด๋ จํ์ฌ ์์ ์ฌํญ์ด ์์ผ๋ฉด ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ค์ ํด์ฃผ์ด์ผ๋ฉ๋๋ค.
4. admin ์ ๋ชจ๋ธ Class ๋ฑ๋กํ๊ธฐ
๋ชจ๋ธ๋ ์์ฑํ๊ณ , migrate๋ ๋๋์ต๋๋ค. admin.py๋ฅผ ์ด์ด์ฃผ๊ณ ๋ฑ๋ก(regist)์์ผ์ฃผ๋ฉด ๋ฉ๋๋ค.
admin์ ์ฅ๊ณ ์์ ์ ๊ณตํ๋ ๊ด๋ฆฌ์ ํ์ด์ง์ ๋๋ค. ์ด๊ณณ์์ ์ญ์ , ์ถ๊ฐ ๋ฑ์ ์์ ์ ํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ๋ฐฉ๊ธ ์์ฑํ modelํด๋์ค๋ฅผ ๋ฑ๋กํ์ฌ admin์์ ์ฌ์ฉํ๊ธฐ ์ํจ์ ๋๋ค.
from django.contrib import admin
from .models import User #๊ฐ์ ๊ฒฝ๋ก์ models.py์์ User๋ผ๋ ํด๋์ค๋ฅผ ์ํฌํธํ๋ค.
# Register your models here.
class UserAdmin(admin.ModelAdmin) :
list_display = ('username', 'password')
admin.site.register(User, UserAdmin) #site์ ๋ฑ๋ก
admin.ModelAdmin :์ ์์๋ฐ๊ฒ ๋๋ฉด, adminํ์ด์ง์์ ์ด๋ ํ Column์ ๊ด๋ฆฌํ ์ง ๋ฑ์ ๋ํ ์ค์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
list_display : ๊ด๋ฆฌ์ ํ์ด์ง์์ ๋ณผ Column์ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
๊ด๋ฆฌ์ ํ์ด์ง๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์ํผ๊ณ์ ์ด ํ์ํฉ๋๋ค.
์ํผ๊ณ์ ์์ฑ
ํฐ๋ฏธ๋ ์
๋ ฅ
python manage.py createsuperuser
์ ๋ช ๋ น์ด๋ฅผ ํตํด ์ํผ๊ณ์ ์ ์์ฑํ ์ ์์ต๋๋ค. ์๋ฒ ์คํํ adminํ์ด์ง๋ฅผ ํ์ธํ ๋ ํ์ํ๋ ๋ง๋ค์ด์ค๋๋ค.
5. ์๋ฒ ์คํํด๋ณด๊ธฐ
ํฐ๋ฏธ๋์
๋ ฅ
python manage.py runserver
์ ๋ช ๋ น์ด๋ก ์๋ฒ๋ฅผ ์คํ์ํจ ๋ค http://127.0.0.1:8000/admin ํ์ด์ง๋ก ๋ค์ด๊ฐ๋๋ค.
๋ค์ด๊ฐ๋ฉด ๋ก๊ทธ์ธ์ ํ๋ผ๊ณ ๋์ฌํ ๋ฐ, ๋ฐฉ๊ธ๋ง๋ ์ํผ๊ณ์ ์ ์ ๋ ฅํ๋ฉด ๋ฉ๋๋ค.
๋๋ฒ์งธ ์ค์ USER (App)๋ผ๋ ์ฑ์ด ์์ฑ๋์๊ณ , Users๋ผ๋ ๋ชจ๋ธ์ด ์์ฑ๋จ์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ ์๋์ผ๋ก ๋ณต์ํ์ด ์ ์ฉ๋์ด Users๊ฐ ๋๋๋ฐ์, ์ด ๋ถ๋ถ์ models.py์์ ์์ ๊ฐ๋ฅํฉ๋๋ค.
(verbose_name_plural = "Users ๋์ ์ฌ์ฉํ ์ด๋ฆ")
๊ทธ๋ผ Users๋ฅผ ํ๋ฒ ํด๋ฆญํด ๋ด ๋๋ค.
ํด๋ฆญํ๋ฉด user object๋ผ๋๊ฒ ๋์ต๋๋ค. ๊ฐ๋ ์ฑ์ ์ํด username์ด ์ถ๋ ฅ๋๋๋ก ๋ฐ๊ฟ๋๋ค.
Admin ํ์ด์ง
*userํด๋ - models.py
from django.db import models
# Create your models here.
class User(models.Model): #์ฅ๊ณ ์์ ์ ๊ณตํ๋ models.Model๋ฅผ ์์๋ฐ์์ผํ๋ค.
username = models.CharField(max_length=64,verbose_name = '์ฌ์ฉ์๋ช
')
password = models.CharField(max_length=64,verbose_name = '๋น๋ฐ๋ฒํธ')
registered_dttm = models.DateTimeField(auto_now_add=True,verbose_name='๋ฑ๋ก์๊ฐ')
def __str__(self): # ์ด ํจ์ ์ถ๊ฐ
return self.username # User object ๋์ ๋ํ๋ผ ๋ฌธ์
class Meta:
db_table = 'test_user'
Userํด๋์ค๋ก๋ถํฐ ์ถ๋ ฅ๋๋ ๊ธฐ๋ณธ ๋ฌธ์์ด์ ์ฌ์ฉ์์ ์์๋ก ์ค์ ํด์ค๋๋ค. __Str__ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ฆฌํด๊ฐ์ ๋ง๋ค์ด ์ค๋๋ค.
return ๋ค์ ์ถ๋ ฅ๋๊ธฐ ์ํ๋๊ฒ์ ์ ๋ ฅํ๋ฉด ๋ฉ๋๋ค.
6. ํ์๊ฐ์ ํ์ด์ง ์ค์ (view)
ํ์๋ฑ๋ก ํจ์ ์์ฑ
*userํด๋ - views.py
from django.shortcuts import render
# Create your views here.
def register(request): #ํ์๊ฐ์
ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ํจ์
return render(request, 'register.html') #register๋ฅผ ์์ฒญ๋ฐ์ผ๋ฉด register.html ๋ก ์๋ต.
django.shortcuts - render : register ํจ์๋ฅผ ์คํํ๋ฉด, register.html์ renderํ์ฌ ๋ฐํํฉ๋๋ค.
URL ์ค์ ํ๊ธฐ
*ํ๋ก์ ํธ ํด๋ - urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('user/', include('user.urls'))
#127.0.0.1:8000/user/ ์ดํ์ url๋ค์ userํด๋์ urlsํ์ผ์์ ๊ด๋ฆฌํ๋ค. ๋ผ๋ ์ค์
]
ํ์๊ฐ์ ์ ๋ง๋ค๊ณ ๋์์ ํ์ด์ง๋ฅผ ์ด๋ค url์์ ๋ํ๋ด ์ค์ง ์ค์ ํฉ๋๋ค.
include๊ธฐ๋ฅ์ ํตํด userํด๋์ urls ํ์ผ๋ก ์ฐ๊ฒฐํด์ค๋๋ค.
*userํด๋ - urls.py
์ฑ์ ์์ฑํ ์ด๊ธฐ์๋ urls.py๊ฐ ์์ผ๋ฏ๋ก, ์๋ก์ด ํ์ผ์ ํ๋ ๋ง๋ค์ด์ ์ ๋ ฅํด์ค๋๋ค.
from django.urls import path
from . import views
urlpatterns = [
path('register/',views.register),
#์ฆ, ์ต์ข
์ ์ธ url์ 127~~~~:8000/user/register๊ฐ ๋๋ค.
]
7. ํ์๊ฐ์ ํ์ด์ง ํ๋ฉด ๋ง๋ค๊ธฐ (HTML ์์ฑ)
*userํด๋ - templatesํด๋ - register.html
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div class= "container">
<div class = "row mt-5">
<div class = "col-12 text-center">
<h1>ํ์๊ฐ์
</h1>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!-- ํผ ์์๋ค๊ฐ ์
๋ ฅํด์ค์ผํ๋ค. (์์จ์ฃผ๋ฉด ์๋ฌ๋ฐ์)
csrf_token ํผ์ ๊ฒฝ์ฐ์๋ , ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์ ์ ๋ฌํ๋ ๊ธฐ๋ฅ.์ด๋ ์ํธํ๋ ํค๋ฅผ ์จ๊ฒจ๋์ ํฌ๋ก์ค๋๋ฉ์ธ์ ๋ง๊ธฐ ์ํจ. -->
<!-- bootstrap -component - forms -->
<div class= "container">
<div class = "row mt-5">
{{error}}
<div class = "col-12 ">
<div class = "row mt-5">
<div class = "col-12 ">
<form method = "POST" action = ".">
{% csrf_token %}
<div class="form-group">
<label for="username">์ฌ์ฉ์ ์ด๋ฆ</label>
<input
type="text"
class="form-control"
id="username"
placeholder="์ฌ์ฉ์ ์ด๋ฆ"
name="username">
<!-- ์ด name ๊ฐ์ผ๋ก ์ ๋ณด๊ฐ ์ ๋ฌ๋๋ค -->
</div>
<div class="form-group">
<label for="password">๋น๋ฐ๋ฒํธ</label>
<input type="password"
class="form-control"
id="password"
placeholder="๋น๋ฐ๋ฒํธ"
name= "password">
</div>
<div class="form-group">
<label for="re_password">๋น๋ฐ๋ฒํธ ํ์ธ</label>
<input
type= "password"
class="form-control"
id="re_password"
placeholder="๋น๋ฐ๋ฒํธ ํ์ธ"
name = "re_password">
</div>
<button type="submit" class="btn btn-primary">๋ฑ๋ก</button>
</form>
</body>
</html>
์ฌ์ฉ์ ์ด๋ฆ, ๋น๋ฐ๋ฒํธ, ๋น๋ฐ๋ฒํธ ํ์ธ์ ์ ๋ ฅ๋ ๋ฐ์ดํฐ๋ฅผ registerํด๋์ค๋ก ๋ฐ์ ์ฌ ์ ์๋๋ก ํ๊ทธ๋ด๋ถ์ id, name ๊ฐ์ ๋ฐ๊พธ์ด์ค๋๋ค.
{% csrf_token %} : ํ์ด์ง์ ํผ์ ์ํธํํ๋ ์์ ์ ๋๋ค. ๋ค๋ฅธ ์ฌ์ดํธ์์ ์์ , ์ญ์ ๋ฑ์ ๊ณต๊ฒฉ์ ๋ง๊ธฐ ์ํ ์ฅ๊ณ ์์ ์ ๊ณตํ๋ ํ ํฐ์ ๋๋ค.
userํด๋ - view.py
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.hashers import make_password
from .models import User
# Create your views here.
def register(request): #ํ์๊ฐ์
ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ํจ์
if request.method == "GET":
return render(request, 'register.html')
elif request.method == "POST":
username = request.POST.get['username',None] #๋์
๋๋ฆฌํํ
password = request.POST.get['password',None]
re_password = request.POST.get['re_password',None]
res_data = {}
if not (username and password and re_password) :
res_data['error'] = "๋ชจ๋ ๊ฐ์ ์
๋ ฅํด์ผ ํฉ๋๋ค."
if password != re_password :
# return HttpResponse('๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฆ
๋๋ค.')
res_data['error'] = '๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฆ
๋๋ค.'
else :
user = User(username=username, password=make_password(password))
user.save()
return render(request, 'register.html', res_data) #register๋ฅผ ์์ฒญ๋ฐ์ผ๋ฉด register.html ๋ก ์๋ต.
request.POST.get['username',None] : POST๋ก ๋ฐ์์จ ๋ฐ์ดํฐ์ 'username'์ด๋ผ๋ key๊ฐ์ ์ด์ฉํ์ฌ value๋ฅผ ๋ฐ์ต๋๋ค. ๋ง์ฝ, value๊ฐ ์๋ค๋ฉด None์ ๋ฐํํฉ๋๋ค.
make_password() : ๊ดํธ ์์ ๋ค์ด๊ฐ ๋ฌธ์์ด์ ์ํธํํฉ๋๋ค.
res_data : ์ html ํ์ผ์์ {{error}}์ ๋งตํ๋์ด ์ฒ๋ฆฌ๋ฉ๋๋ค. ์ฆ, if๋ฌธ์์ ๊ฑธ๋ฆฌ๋ฉด ๋ค์ ๋ฌธ์์ด์ด ์ถ๋ ฅ๋ฉ๋๋ค.
*static ํด๋ ์ค์ ํ๊ธฐ
ํ๋ก์ ํธ ํด๋์ setting.py์์ staticํด๋๋ง ์ค์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'), # base_dir์ ํ๋ก์ ํธ ํด๋
]
๊ทธ๋ฆฌ๊ณ ํ๋ก์ ํธํด๋ ๋ฐ๋ก ํ์์ static ์ด๋ ํด๋๋ฅผ ๋ง๋ค๊ณ , js cssํ์ผ๋ฑ์ ๋ฃ๊ณ , ์ฌ์ฉํ๋ฉด๋ฉ๋๋ค.
'๐ ํ์ด์ฌ (Python)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋น์ ์ด ์ข์ํ ๋งํ ์ฝํ ์ธ
-
ํ์ด์ฌ(python) ๋ฆฌ์คํธ ์ค๋ณต ์์ ๊ฐ์ ์ฐพ๊ธฐ (์นด์ดํ ) or ์ ๊ฑฐ,์ญ์ ํ๊ธฐ (try , except , count) 2020.01.23
-
ํ์ด์ฌ (Python) ๋ฌธ์ ์ ๋ ฅ, map(), split() , sys.stdin.readline() , rstrip() 2020.01.21
-
์ฅ๊ณ (Django) - ์ค์น , ํ๋ก์ ํธ ์์ํ๊ธฐ, ์ฑ ๋ง๋ค๊ธฐ , ์ฑ ๋ฑ๋กํ๊ธฐ 2019.12.28
-
์ปดํจํฐ์ ๋์ ๋ฐฉ์, ํ์ด์ฌ์ ๋์ ๋ฐฉ์ ๊ธฐ๋ณธ ๊ฐ๋ 2019.12.26
์์คํ ๊ณต๊ฐ ๊ฐ์ฌํฉ๋๋ค