๋ณธ ํ๋ก์ ํธ๋ ํจ์บ ๊ฐ์๋ฅผ ์ฐธ๊ณ ํฉ๋๋ค.
<์ด์ ๊ธ>
https://silvercoding.tistory.com/13
[DJANGO ๊ธฐ์ด] 3. Django admin, ๊ฐ๋ฐ ์๋ฒ ํ์ฉ
๋ณธ ํ๋ก์ ํธ๋ ํจ์บ ๊ฐ์๋ฅผ ์ฐธ๊ณ ํฉ๋๋ค. <์ด์ ๊ธ> https://silvercoding.tistory.com/12 https://silvercoding.tistory.com/11 [DJANGO ๊ธฐ์ด] ๊ฐ์ํ๊ฒฝ ์ค์ ๋ฐ ์ฑ ์์ฑ ํ๋ ์ ์ํฌ - ์์ฃผ ์ฌ์ฉ๋๋ ์ฝ๋๋ฅผ..
silvercoding.tistory.com
Tamplate์ Bootstrap ์ ์ด์ฉํ์ฌ ์์ฑํด์ค๋ค.
์์
์ ํ ๋ ์ ์ฅํ๋ ์ต๊ด์ ๊ผญ ๋ค์ฌ์ผ ํ ๊ฒ ๊ฐ๋ค. ์ ์ฅ ์ํ๊ณ ํ์ด์ง ์คํํด์ ์๋ฌ๋ฌ๊ฒ๋ง ์ค์ฒ๋ง๋ฒ์ด๋ค.
Bootstrap ์ด์ฉ์ ์ํด ๋ค์ ๋งํฌ์์ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๋ฉด ๋๋ค.
https://getbootstrap.com/docs/5.0/getting-started/introduction/
Introduction
Get started with Bootstrap, the world’s most popular framework for building responsive, mobile-first sites, with jsDelivr and a template starter page.
getbootstrap.com
ํ์๊ฐ์
์ฐฝ ๋ง๋ค๊ธฐ
1. Template ์์ฑํ๊ธฐ
user ํด๋ ---> templates ํด๋ ---> register.html
Getting started -- CSS ๋ถ๋ถ๊ณผ Javascript ๋ถ๋ถ์ head ํ๊ทธ ์์ ๋ฃ์ด์ค๋ค. starter template ์์ meta ํ๊ทธ๋ ๊ฐ์ ธ์ ์ค๋ค.
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js" integrity="sha384-Atwg2Pkwv9vp0ygtn1JAojH0nYbwNJLPhwyoVbhoPwBhjQPR5VtM2+xf0Uwh9KtT" crossorigin="anonymous"></script>
</head>
<body>
</body>
</html>
๊ทธ๋ผ ์ฐ์ ์ด๋ฐ ๋ชจ์์ ๋๋ค.
Forms --- Overview ์ฝ๋๋ฅผ ๊ฐ์ ธ์จ๋ค!
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js" integrity="sha384-Atwg2Pkwv9vp0ygtn1JAojH0nYbwNJLPhwyoVbhoPwBhjQPR5VtM2+xf0Uwh9KtT" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="col-12 text-center">
<h1>ํ์๊ฐ์
</h1>
</div>
</div>
<div class="row">
<form>
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
<div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1">
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">Check me out</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</body>
</html>
ํ์๊ฐ์
๊ธ์จ ๋ฃ์ด์ฃผ๊ณ ๊ทธ ๋ฐ์ ํ์๊ฐ์
form์ ๋ฃ์ด์ฃผ์๋ค.
ํด๋์ ์ ์ฅ๋ register.html ์ ์ด์ด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์คํ์ด ๋๋ค.
๋์์ธ์ด ๋ง์์ ์๋๋ ๋ฐ๊พธ์ด ์ค๋ค.
- ํ๊ธ๋ก ๋ฐ๊พธ๊ธฐ, container ์ ์ฉ, placeholder ์์ฑํด์ฃผ๊ธฐ
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js" integrity="sha384-Atwg2Pkwv9vp0ygtn1JAojH0nYbwNJLPhwyoVbhoPwBhjQPR5VtM2+xf0Uwh9KtT" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="row-mt5">
<div class="col-12 text-center">
<h1>ํ์๊ฐ์
</h1>
</div>
</div>
<div class="row mt-5">
<form>
<div class="form-group mb-3">
<label for="username" class="form-label">์ฌ์ฉ์ ์ด๋ฆ</label>
<input type="text" class="form-control" id="username" placeholder="์ฌ์ฉ์ ์ด๋ฆ">
</div>
<div class="form-group mb-3">
<label for="password" class="form-label">๋น๋ฐ๋ฒํธ</label>
<input type="password" class="form-control" id="password" placeholder="๋น๋ฐ๋ฒํธ">
</div>
<div class="form-group mb-3">
<label for="re-password" class="form-label">๋น๋ฐ๋ฒํธ ํ์ธ</label>
<input type="password" class="form-control" id="re-password" placeholder="๋น๋ฐ๋ฒํธ ํ์ธ">
</div>
<button type="submit" class="btn btn-primary">๋ฑ๋ก</button>
</form>
</div>
</div>
</body>
</html>
์ํ๋ ๋๋ก ์์ฑ์ด ์๋ฃ ๋์๋ค.
2. View ์์ฑํ๊ธฐ
- community ---> user ---> views.py
from django.shortcuts import render
def register(request):
return render(request, "register.html")
register ํจ์ ์์ฑํ๊ธฐ. request ๋ฅผ ๊ผญ ๊ฐ์ด ์ ๋ฌํด ์ฃผ์ด์ผ ํ๊ณ , ๋ฐํํ๊ณ ์ ํ๋ html ํ์ผ ์ ์์ฑํด ์ค๋ค.
- community --> urls.py
urlpatterns = [
...
path('user/', include('user.urls'))
]
urlpatterns ์์ user ๊ฒฝ๋ก๋ฅผ ์ง์ ํด์ค๋ค.
- community ---> user ---> urls.py
user ํด๋ ์์ urls.py ๋ฅผ ์์ฑํ๋ค.
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.register)
]
views.py ์ register ํจ์๋ฅผ import ํ์ฌ ์ ๋ฌํด์ค๋ค. ์ด๋ ๊ฒ ์์ฑ์ ํด๋์ผ๋ฉด .../user/register ๊ฒฝ๋ก๋ฅผ ์น๋ฉด register.html ์ด ๋ ๋๋ง ๋ ๊ฒ์ด๋ค.
- ๊ฐ๋ฐ์ ์๋ฒ ๋ค์ด๊ฐ๋ณด๊ธฐ
ํฐ๋ฏธ๋
python manage.py runserver
์ด์ ์๋ฒ๋ก ๋ค์ด๊ฐ์ ํ์ธ์ ํด๋ณด์.
ํฐ๋ฏธ๋์ ๋จ๋ ์ฃผ์ ๋ค์ /user/register ์์ฑ์ ํด์ค๋ค.
๊ทธ๋ฌ๋ฉด ์ด๋ ๊ฒ ์ ์ฐ๊ฒฐ์ด ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ฐ์ดํฐ๋ฅผ ํ์ด์ฌ ์ชฝ์ผ๋ก ์ ๋ฌ
์ฃผ์๋ฅผ ์ณ์ ํ์๊ฐ์
์ฐฝ์ผ๋ก ๋ค์ด๊ฐ ์ ์๊ฒ ๋์์ผ๋, ์ด์ ๋ POST์์ฒญ์ ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ก ์ ๋ฌํด์ฃผ๋ ์์
์ ํด์ผํ๋ค.
1. Template ์์ฑํ๊ธฐ
community ---> user ---> register.html
...
<form method="POST" , action=".">
{% csrf_token %}
<div class="form-group mb-3">
<label for="username" class="form-label">์ฌ์ฉ์ ์ด๋ฆ</label>
<input type="text" class="form-control" id="username" placeholder="์ฌ์ฉ์ ์ด๋ฆ" name="username">
</div>
<div class="form group mb-3">
<label for="password" class="form-label">๋น๋ฐ๋ฒํธ</label>
<input type="password" class="form-control" id="password" placeholder="๋น๋ฐ๋ฒํธ" name="password">
</div>
<div class="form group mb-3">
<label for="re-password" class="form-label">๋น๋ฐ๋ฒํธ ํ์ธ</label>
<input type="password" class="form-control" id="re-password" placeholder="๋น๋ฐ๋ฒํธ ํ์ธ" name="re-password">
</div>
<button type="submit" class="btn btn-primary">๋ฑ๋ก</button>
</form>
...
๋ฐ์ดํฐ๋ฅผ ํ์ด์ฌ ์ชฝ์ผ๋ก ์ ๋ฌํด์ฃผ๋ ์ฝ๋์ด๋ค. POST method๋ก ์ ๋ฌํ๊ณ , action="."์ ํ์ฌ ์ฃผ์๋ก ์ ๋ฌํ๊ฒ ๋ค๋ ๋ป์ด๋ค.
form ์์ {% csrf_token %} ์ด๊ฒ์ ๊ผญ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค.
form ์ data ๋ฅผ ์๋ฒ์ ์ ๋ฌํ๋ ๊ฒ์ธ๋ฐ, ์์ข๊ฒ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ด ๋ค๋ฅธ ์น์ฌ์ดํธ์์ ๋ฐ์ดํฐ ์ ๋ฌ์ ํ๋ ๊ฒฝ์ฐ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํ ์ฝ๋๋ผ๊ณ ํ๋ค. ํฌ๋ก์ค ๋๋ฉ์ธ์ ๋ง๊ธฐ ์ํด ์ํธํ๋ ํค๋ฅผ ์จ๊ฒจ๋๋๋ค. ๊ทธ๋์ ํค๊ฐ ์์ผ๋ฉด ์๋ชป๋ ์์ฒญ์ผ๋ก ๋ฐ์๋ค์ฌ ์์ฒญ์ ๊ฑฐ์ ํ๊ฒ ๋๋ค. ํ์์ ์ธ ์ฝ๋์ด๊ธฐ ๋๋ฌธ์ ์์จ์ฃผ๋ฉด ์๋ฌ๊ฐ ๋๋ค!
๊ทธ๋ฆฌ๊ณ input ํ๊ทธ์ name ์์ฑ๋ ์ถ๊ฐํด์ค๋ค. ์ด name ๊ฐ์ผ๋ก ์ ๋ณด๊ฐ ์ ๋ฌ์ด ๋ ๊ฒ์ด๋ค.
2. View ์์ฑํ๊ธฐ
community ---> user ---> view.py
from django.shortcuts import render
from .models import User
def register(request):
if request.method == 'GET':
return render(request, "register.html")
elif request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
re_password = request.POST['re-password']
user = User(
Username = username,
password = password
)
user.save()
return render(request, "register.html")
์์ฒญ ๋ฐฉ๋ฒ์ด GET์ผ ๋์ POST ์ผ ๋๋ฅผ ๋ค๋ฅด๊ฒ ์์ฑํด ์ฃผ์ด์ผ ํ๋ค.
์ฌ๊ธฐ๊น์ง ํด์ silver 123456 ์ผ๋ก ํ์๊ฐ์
์ ํ๊ณ admin์ ๋ค์ด๊ฐ ๋ณด๋ user ์์ฑ์ด ์ ๋์ด์๋ค.
3. ๋น๋ฐ๋ฒํธ ํ์ธํ๊ธฐ
community ---> user ---> view.py .py
from django.shortcuts import render
from .models import User
def register(request):
if request.method == 'GET':
return render(request, "register.html")
elif request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
re_password = request.POST['re-password']
res_data = {}
if password != re_password:
res_data['error'] = "๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฆ
๋๋ค."
else:
user = User(
Username = username,
password = password
)
user.save()
return render(request, "register.html", res_data)
res_data๋ผ๋ dictionary๋ฅผ ์์ฑํด์ฃผ๊ณ password์ re_password์ ๊ฐ์ด ๋ค๋ฅด๋ฉด res_data์ ํค๊ฐ์ error, value๊ฐ์ ๋ฌธ์์ด๋ก ์ ์ฅํด์ค๋ค. ๊ทธ๋ค์ render ํจ์์ res_data๋ฅผ ์ ๋ฌํด ์ค๋ค.
community ---> user ---> register.html
...
<div class="row-mt5">
<div class="col-12 text-center">
<h1>ํ์๊ฐ์
</h1>
</div>
</div>
<div class="row mt-5">
<div class="col-12">
{{error}}
</div>
</div>
...
๊ทธ๋ค์ ํ์๊ฐ์
๋ฐ์ ์๋ฌ ๋ฌธ์์ด์ ๊ทธ๋ ค์ค ๋ถ๋ถ์ ํ๋ ๋ง๋ ๋ค. {{}} ์์ res_data์ ํค ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
register.html ์ ๋๋๋ง์ ํ ๋ res_data ๋ผ๋ ๊ฐ์ ๋๊ธฐ๋ฉด res_data์ ํค ์ {{error}} ๊ฐ ๋งคํ์ด ๋๋ค.
--- ํ์ธํด๋ณด๊ธฐ
๋น๋ฐ๋ฒํธ๋ฅผ ๋ค๋ฅด๊ฒ ์น๋ฉด ์์๊ฐ์ด ๋์ค๋ ๊ฒ์ ํ์ธ ํด ๋ณด์๋ค.
4. ๋ชจ๋ ๊ฐ์ด ์
๋ ฅ๋์ง ์์์ ๋ ์ฒ๋ฆฌ & ๋น๋ฐ๋ฒํธ ์ํธํ
์์๊น์ง ์์
์ ๋ง์ณค์ ๋ ๋ฌธ์ ์ ์ด ์๋ค.
์ฌ์ฉ์ ์ด๋ฆ, ๋น๋ฐ๋ฒํธ, ๋น๋ฐ๋ฒํธ ํ์ธ์ ์์ฑํ์ง ์์๋ ์๋ฌ ๋ฉ์์ง๊ฐ ๋จ์ง ์์ผ๋ฉฐ,
์ฌ์ง๊ณผ ๊ฐ์ด ๋น๋ฐ๋ฒํธ๊ฐ ๊ณต๊ฐ๋๋ฏ๋ก ๋ฌธ์ ๊ฐ ๋ ์ ์๋ค. ๋ฐ๋ผ์ ๋น๋ฐ๋ฒํธ ์ํธํ๊น์ง ์์ฑ์ ํด์ค๋ค.
community ---> user ---> view.py .py
from django.shortcuts import render
from .models import User
from django.contrib.auth.hashers import make_password
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'] = "๋ชจ๋ ๊ฐ์ ์
๋ ฅํด์ฃผ์ธ์."
elif password != re_password:
res_data['error'] = "๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฆ
๋๋ค."
else:
user = User(
Username = username,
password = make_password(password)
)
user.save()
return render(request, "register.html", res_data)
์ต์ข
์ ์ผ๋ก ์ด๋ ๊ฒ ์์ฑ ์๋ฃ. makepassword๋ฅผ importํ์ฌ password๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋น๋ฐ๋ฒํธ ์ํธํ๊ฐ ๋๋ค. ๊ทธ๋ฆฌ๊ณ request.POST์ getํจ์๋ฅผ ์ด์ฉํ์ฌ ๊ธฐ๋ณธ ๊ฐ์ None์ผ๋ก ์ค์ ํด์ค๋ค. ๊ทธ๋ค์ username, password, re_password๋ฅผ and๋ก ์ฐ๊ฒฐํด์ฃผ์ด ํ๋๋ผ๋ ์์ฑ์ด ๋์ง ์์ผ๋ฉด error ๋ฉ์์ง๊ฐ ๋จ๊ฒ ์์ฑํด์ค๋ค.
๊ฒฐ๊ณผ ํ์ธ
๋ชจ๋ ๊ฐ์ ์
๋ ฅํ์ง ์์๋๋ ์๋ฌ ๋ฉ์์ง๊ฐ ๋ฌ๋ค.
silver2๋ก ๊ฐ์
์ ๋ค์ ํด์ฃผ์๋๋ ์ํธํ๋ ๋น๋ฐ๋ฒํธ๋ก ๋จ๋ ๊ฒ์ ์ ์ ์๋ค.
--- ์ฌ๊ธฐ์ model์ field(ex, ์ฌ์ฉ์ ์ด๋ฉ์ผ) ๋ฅผ ์ถ๊ฐํ๊ธฐ ์ํ ์ ์ฐจ (ํฌ์คํ
์ ์๋ต)
model field ์์ฑ ---> migration ---> register.html ์์ฑ ---> view.py ์์ฑ
์ฌ์ฉ์ ์ด๋ฉ์ผ field๋ฅผ ์ถ๊ฐํ ๊ฒฐ๊ณผ์ด๋ค.
์ ๋ง ๊ธด ์ฌ์ ์ด์๋ค. ๋ค์์๋ static ํ์ผ ๊ด๋ฆฌ์ CDN ์ ๋ํ์ฌ ์์๋ณผ ์์ ์ด๋ค.