TIL_220530_Django ๊ธฐ์ด
- -
Django ์ ๊ธฐ๋ณธ user ๋ชจ๋ธ(auth_user) ์ฌ์ฉํ๊ธฐ (์์)
1) ์์ํ๊ธฐ ์ํ AbstractUser ์ํฌํธ
from django.db import models
from django.contrib.auth.models import AbstractUser
2) UserModel ์ ์์
- ๊ธฐ๋ณธ ๋ชจ๋ธ์ ์๋ bio ๋ฐ์ดํฐ ์ถ๊ฐ
# Create your models here.
class UserModel(AbstractUser):
class Meta:
db_table = "my_user" # ์ฌ๊ธฐ๋ ํ
์ด๋ธ ์ด๋ฆ์ด์์! ๊ผญ ๊ธฐ์ต ํด ์ฃผ์ธ์!
bio = models.TextField(max_length=500, blank=True)
3) ํ๋ก์ ํธ์ฑ์ settings.py ์ ๊ธฐ๋ณธ ์ธ์ฆ๊ณผ์ ์ ์ฉ
- Django ์๊ฒ ๊ธฐ๋ณธ ์ธ์ฆ๊ณผ์ (AUTH_USER_MODEL) ์ user ์ฑ์ ์์ฑํ UserModel ๋ก ์ฌ์ฉ
# mySpartaSns/settings.py
AUTH_USER_MODEL = 'user.UserModel'
4) ์๋ก์ด ๋ชจ๋ธ ์ ์ฉ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฉ์ํค๊ธฐ
- python manage.py makemigrations
- python manage.py migrate
Django์ ์ฌ์ฉ์ ๋ชจ๋ธ์ ์ ์ฉํ๊ธฐ - ํ์๊ฐ์ ์์ ํ๊ธฐ
1) user/views.py ์์ ํ์๊ฐ์ ๊ธฐ๋ฅ ์์
- ํ์๊ฐ์ ์ค๋ณต๊ฒ์ฌ๋ฅผ ์ํด get_user_model ์ ์ํฌํธ
# user/views.py
from django.contrib.auth import get_user_model #์ฌ์ฉ์๊ฐ ์๋์ง ๊ฒ์ฌํ๋ ํจ์
2) ํ์๊ฐ์ ์ฌ์ฉ ํจ์์ get_user_model ์ ์ฉ
- get_user_model().objects.filter(username=username) ์ผ๋ก username ๋ฐ์ดํฐ ๋์กฐ
exist_user = get_user_model().objects.filter(username=username)
if exist_user:
return render(request, 'user/signup.html') # ์ฌ์ฉ์๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๋ฅผ ์ ์ฅํ์ง ์๊ณ ํ์๊ฐ์
ํ์ด์ง๋ฅผ ๋ค์ ๋์
else:
UserModel.objects.create_user(username=username, password=password, bio=bio)
return redirect('/sign-in') # ํ์๊ฐ์
์ด ์๋ฃ๋์์ผ๋ฏ๋ก ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋
Django์ ์ฌ์ฉ์ ๋ชจ๋ธ์ ์ ์ฉํ๊ธฐ - ๋ก๊ทธ์ธ ์์ ํ๊ธฐ
1) ์ฌ์ฉ์ ๋ชจ๋ธ ์ ์ฉ์ ์ํ ๋ก๊ทธ์ธ ์์
- ์ฌ์ฉ์ auth ๊ธฐ๋ฅ ์ํฌํธ
# user/views.py
from django.contrib import auth # ์ฌ์ฉ์ auth ๊ธฐ๋ฅ
2) ๋ก๊ทธ์ธ์ views.py ์์
- auth.authenticate() ๋ฅผ ์ฌ์ฉํด ์ฌ์ฉ์ ์ ๋ณด ๋ถ๋ฌ์ค๊ธฐ ๋ฐ ์ฒดํฌ
- auth.login(request, me) ๋ก ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ์น์ธ
me = auth.authenticate(request, username=username, password=password) # ์ฌ์ฉ์ ๋ถ๋ฌ์ค๊ธฐ
if me is not None: # ์ ์ฅ๋ ์ฌ์ฉ์์ ํจ์ค์๋์ ์
๋ ฅ๋ฐ์ ํจ์ค์๋ ๋น๊ต
auth.login(request, me)
return HttpResponse("๋ก๊ทธ์ธ ์ฑ๊ณต")
else:
return redirect('/sign-in') # ๋ก๊ทธ์ธ ์คํจ
3) ๋ก๊ทธ์ธ ์น์ธ ํ ๋ฉ์ธ ํ์ด์ง ์ด๋ ์ฐ๊ฒฐ
- tweet/home.html ๋ฉ์ธ์ด ๋๋ ํ์ด์ง๋ฅผ ์์ฑ
- base.html ์ ๊ธฐ๋ฐ {% extends 'base.html' %} ์ผ๋ก {% block content %} & {% endblock %} ์์ญ ์์ฑ
4) ์ด๋ํ ๋ฉ์ธ ํ์ด์ง ์ฐ๊ฒฐ
- ๊ธ์ฐ๊ธฐ ๊ธฐ๋ฅ์ด ํฌํจ๋ ๋ฉ์ธ ํ์ด์ง๋ก tweet ์ฑ์ views.py ๋ด์ฉ ์ถ๊ฐ
- request.user.is_authenticated ์ฌ์ฉ์๊ฐ ์ธ์ฆ์ ๋ฐ์๋์ง(๋ก๊ทธ์ธ์ด ๋์ด์๋์ง)
# tweet/views.py
from django.shortcuts import render, redirect
# Create your views here.
def home(request):
user = request.user.is_authenticated # ์ฌ์ฉ์๊ฐ ์ธ์ฆ์ ๋ฐ์๋์ง (๋ก๊ทธ์ธ์ด ๋์ด์๋์ง)
if user:
return redirect('/tweet')
else:
return redirect('/sign-in')
def tweet(request):
if request.method == 'GET':
return render(request, 'tweet/home.html')
5) tweet ์ฑ์ urls.py ์์ฑ
# tweet/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'), # 127.0.0.1:8000 ๊ณผ views.py ํด๋์ home ํจ์ ์ฐ๊ฒฐ
path('tweet/', views.tweet, name='tweet') # 127.0.0.1:8000/tweet ๊ณผ views.py ํด๋์ tweet ํจ์ ์ฐ๊ฒฐ
]
6) ํ๋ก์ ํธ ์ฑ์ urls.py ์์ ์ฃผ์ ๋ฑ๋ก
# mySpartaSns/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('user.urls')),
path('', include('tweet.urls'))
]
๋ก๊ทธ์ธ ์ฌ์ฉ์ ๊ธฐ๋ฅ ํ์
1) ๋ก๊ทธ์ธ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๋ ธ์ถํ๊ธฐ ์ํ ํ ํ๋ฆฟ ์ค์
- '{{ }}' ์ ์ฌ์ฉํด์ ๋ ธ์ถ ํ๊ทธ ๋ถ๋ถ์ ์ฌ์ฉ์ ์ด๋ฆ : {{ user.username }} & ์ฌ์ฉ์ ์ ๋ณด : {{ user.bio }} ๋ฅผ ๊ฐ๊ฐ ์ ๋ ฅ
<div class="col-md-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ user.username }}</h5>
<p class="card-text"> {{ user.bio }}</p>
</div>
</div>
</div>
2) ํ๋ฉด์ ์ ๋ณด๊ฐ ๋ด๊ธด ๋ค๋น๊ฒ์ด์ ๋ฐ์์ ์ฌ์ฉ์ ์ ๋ณด์ ๋ง๊ฒ ๋ณํ๋ ์์ญ์ ์ฌ์ฉ์ ์ธ์ฆ ์กฐ๊ฑด์ ๋ง๊ฒ ์ค์
- {% if not user.is_authenticated %} : ์ฌ์ฉ์ ๋ก๊ทธ์ธ ํ์ธ์ด ์๋๋ค๋ฉด ๋ก๊ทธ์ธ, ํ์๊ฐ์ ๋ ธ์ถ
- {% else %} : ์ฌ์ฉ์ ๋ก๊ทธ์ธ ํ์ธ์ด ๋๋ค๋ฉด {{ user.username }} ์ผ๋ก ์ฌ์ฉ์์ ์ด๋ฆ ์ ๋ณด ๋ ธ์ถ
- {% endif %} ๋ก ์กฐ๊ฑด ๋ง๋ฌด๋ฆฌ
<!-- templates/base.html -->
<form class="form-inline my-2 my-lg-0">
{% if not user.is_authenticated %}
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/sign-in"> Sign In <span class="sr-only"></span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/sign-up"> Sign Up <span class="sr-only"></span></a>
</li>
</ul>
{% else %}
{{ user.username }} ๋ ๋ฐ๊ฐ์ต๋๋ค!
{% endif %}
</form>
3) ๋ก๊ทธ์ธ์ ํ์ ๊ธฐ๋ฅ ๋ก๊ทธ์ธ ์ฌ์ฉ์ ์ ํ
- ๋ก๊ทธ์ธ ์ฌ์ฉ์ ํ๋จ๊ณผ ํด๋นํ๋ ์กฐ๊ฑด ์ ์ฉ์ ์ํด tweet ์ฑ์ views.py ์์
- user = request.user.is_authenticated ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ์ด ๋์ด ์๋์ง ํ์ธํ๊ธฐ
# user/views.py
def sign_in_view(request):
if request.method == 'POST':
username = request.POST.get('username', None)
password = request.POST.get('password', None)
me = auth.authenticate(request, username=username, password=password) # ์ฌ์ฉ์ ๋ถ๋ฌ์ค๊ธฐ
if me is not None: # ์ ์ฅ๋ ์ฌ์ฉ์์ ํจ์ค์๋์ ์
๋ ฅ๋ฐ์ ํจ์ค์๋ ๋น๊ต
auth.login(request, me)
return redirect('/')
else:
return redirect('/sign-in') # ๋ก๊ทธ์ธ ์คํจ
elif request.method == 'GET':
user = request.user.is_authenticated # ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ๋์ด ์๋์ง ๊ฒ์ฌ
if user: # ๋ก๊ทธ์ธ์ด ๋์ด ์๋ค๋ฉด
return redirect('/')
else: # ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด
return render(request, 'user/signin.html')
4) ๋ก๊ทธ์ธ ์ ํ์๊ฐ์ ํ์ด์ง๋ ๋ถํ์ํ ํ์ด์ง์ด๋ฏ๋ก ํ์ด์ง ์ ๊ทผ์ ์ฐํํ๊ธฐ ์ํ ํจ์ ์์
- ๋ก๊ทธ์ธ ์กฐ๊ฑด ํจ์์ ๋๊ฐ์ด user = request.user.is_authenticated ๋ก๊ทธ์ธ ์ฌ๋ถ ํ๋จ
# user/views.py
def sign_up_view(request):
if request.method == 'GET':
user = request.user.is_authenticated # ๋ก๊ทธ์ธ ๋ ์ฌ์ฉ์๊ฐ ์์ฒญํ๋์ง ๊ฒ์ฌ
if user: # ๋ก๊ทธ์ธ์ด ๋์ด์๋ค๋ฉด
return redirect('/')
else: # ๋ก๊ทธ์ธ์ด ๋์ด์์ง ์๋ค๋ฉด
return render(request, 'user/signup.html')
elif request.method == 'POST':
username = request.POST.get('username', None)
password = request.POST.get('password', None)
password2 = request.POST.get('password2', None)
bio = request.POST.get('bio', None)
if password != password2:
return render(request, 'user/signup.html')
else:
exist_user = get_user_model().objects.filter(username=username)
if exist_user:
return render(request, 'user/signup.html') # ์ฌ์ฉ์๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๋ฅผ ์ ์ฅํ์ง ์๊ณ ํ์๊ฐ์
ํ์ด์ง๋ฅผ ๋ค์ ๋์
else:
UserModel.objects.create_user(username=username, password=password, bio=bio)
return redirect('/sign-in') # ํ์๊ฐ์
์ด ์๋ฃ๋์์ผ๋ฏ๋ก ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋
5) ๋ก๊ทธ์์ ๊ธฐ๋ฅ
- views.py ๋ก๊ทธ์์ ํจ์ ์ถ๊ฐ
- @login_requred ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์๋ง ์ ๊ทผํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ / ๋ก๊ทธ์์์ ํ์ฑํํ๊ธฐ ์ํ ์กฐ๊ฑด
#user/views.py
from django.contrib.auth.decorators import login_required
@login_required
def logout(request):
auth.logout(request) # ์ธ์ฆ ๋์ด์๋ ์ ๋ณด๋ฅผ ์์ ๊ธฐ
return redirect("/")
- urls.py ์ฐ๊ฒฐ
# user/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('sign-up/', views.sign_up_view, name='sign-up'),
path('sign-in/', views.sign_in_view, name='sign-in'),
path('logout/', views.logout, name='logout')
]
- ๋ก๊ทธ์ธ ์ฌ์ฉ์ ๊ธฐ๋ฅ์์ ์ถ๊ฐํ๋ html ์ ํ ํ๋ฆฟ ์ถ๊ฐ
{% else %}
<ul class="navbar-nav mr-auto">
<li class="nav-item" disabled>
<span class="nav-link">
{{ user.username }} ๋ ๋ฐ๊ฐ์ต๋๋ค!
</span>
</li>
<li class="nav-item">
<a class="nav-link" href="/logout"> ๋ก๊ทธ์์ </a>
</li>
</ul>
{% endif %}
๊ฒ์๊ธ ์ฐ๊ธฐ & ์ฝ๊ธฐ & ์ญ์
1) ์ฌ์ home.html ์ ๊ฒ์๊ธ์ด ์ ๋ ฅ ๋ form ํ๊ทธ์ action ๊ณผ method ๋ฅผ ์ฌ์ฉํด django ์ url ๋ก ์ฐ๊ฒฐ
- method = 'post'
- action = '/tweet/'
<form action="/tweet/" method="post">
{% csrf_token %}
<div class="form-group mb-2">
<textarea class="form-control" style="resize: none" name='my-content' id="my-content"></textarea>
</div>
<button type="submit" class="btn btn-primary" style="float:right;">์์ฑํ๊ธฐ</button>
</form>
2) tweet ์ฑ์ ๊ธ์ฐ๊ธฐ views.py ์์
- user = request.user : ์์ฒญ ์ ์๋์ ์ผ๋ก ์ธ์ฆ ์ถ๊ฐ
- my_tweet.content = request.POST.get('my-content','') : home.html ์ input name ๊ฐ์ธ my-content ์ ์
from .models import TweetModel # ๊ธ์ฐ๊ธฐ ๋ชจ๋ธ -> ๊ฐ์ฅ ์๋ถ๋ถ์ ์ ์ด์ฃผ์ธ์!
def tweet(request):
if request.method == 'GET': # ์์ฒญํ๋ ๋ฐฉ์์ด GET ๋ฐฉ์์ธ์ง ํ์ธํ๊ธฐ
user = request.user.is_authenticated # ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ์ด ๋์ด ์๋์ง ํ์ธํ๊ธฐ
if user: # ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์๋ผ๋ฉด
return render(request, 'tweet/home.html')
else: # ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด
return redirect('/sign-in')
elif request.method == 'POST': # ์์ฒญ ๋ฐฉ์์ด POST ์ผ๋
user = request.user # ํ์ฌ ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์๋ฅผ ๋ถ๋ฌ์ค๊ธฐ
my_tweet = TweetModel() # ๊ธ์ฐ๊ธฐ ๋ชจ๋ธ ๊ฐ์ ธ์ค๊ธฐ
my_tweet.author = user # ๋ชจ๋ธ์ ์ฌ์ฉ์ ์ ์ฅ
my_tweet.content = request.POST.get('my-content', '') # ๋ชจ๋ธ์ ๊ธ ์ ์ฅ
my_tweet.save()
return redirect('/tweet')
3) tweet ์ฑ์ views.py GET ํจ์ ์์
- TweetModel() : ๋ก๊ทธ์ธ ์ฌ์ฉ์๋ฅผ ๊ฒ์ฆ ํ ํ ๋ถ๋ฌ์ฃผ๋ ๊ธฐ๋ฅ
- all_tweet = TweetModel.objects.all().order_by('-created_at') : created_at ์ ์ญ์์ผ๋ก ๋ถ๋ฌ์ค๋ ์ฝ๋
- return render(request, 'tweet/home.html', {'tweet': all_tweet}) : tweet/home.html์ ํ๋ฉด์ ๋์ฐ๋ฉด์ {'tweet':all_tweet} ๋ผ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์ ์ ๋ฌ
# tweet/views.py
def tweet(request):
if request.method == 'GET': # ์์ฒญํ๋ ๋ฐฉ์์ด GET ๋ฐฉ์์ธ์ง ํ์ธํ๊ธฐ
user = request.user.is_authenticated # ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ์ด ๋์ด ์๋์ง ํ์ธํ๊ธฐ
if user: # ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์๋ผ๋ฉด
all_tweet = TweetModel.objects.all().order_by('-created_at')
return render(request, 'tweet/home.html', {'tweet': all_tweet})
else: # ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด
return redirect('/sign-in')
elif request.method == 'POST': # ์์ฒญ ๋ฐฉ์์ด POST ์ผ๋
user = request.user # ํ์ฌ ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์๋ฅผ ๋ถ๋ฌ์ค๊ธฐ
my_tweet = TweetModel() # ๊ธ์ฐ๊ธฐ ๋ชจ๋ธ ๊ฐ์ ธ์ค๊ธฐ
my_tweet.author = user # ๋ชจ๋ธ์ ์ฌ์ฉ์ ์ ์ฅ
my_tweet.content = request.POST.get('my-content', '') # ๋ชจ๋ธ์ ๊ธ ์ ์ฅ
my_tweet.save()
return redirect('/tweet')
4) ์์ฑํ ๊ฒ์๊ธ์ ํ๋ฉด์์ผ๋ก ๋ ธ์ถ์ํค๊ธฐ
- for ๋ฌธ ๋ฐ๋ณต๋ฌธ์ html ํ ํ๋ฆฟ์ ์ ์ฉ
<!-- templates/tweet/home.html -->
<hr>
<!-- ์์ฑ ๋ ๊ธ์ด ๋์ค๋ ๊ณณ -->
<div class="row">
{% for tw in tweet %}
<div class="col-md-12 mb-2">
<div class="card">
<div class="card-body">
<div class="media">
<div class="media-body">
<h5 class="mt-0">{{ tw.content }}</h5>
</div>
<div style="text-align: right">
<span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} ์ </span>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
5) ๊ฒ์๊ธ ์ญ์ ๊ธฐ๋ฅ
- views.py ์์ ๊ฒ์๊ธ์ ๋ณธ์ธ ์์ฑ์๋ง ์ญ์ ํ ์ ์๋๋ก ๊ธฐ๋ฅ์ ์ ํํ๊ธฐ ์ํ login_required ์ํฌํธ
- ํจ์์ request ์ id ๋ฅผ ์ ์ฉํด id ์ ํด๋นํ๋ ์ฌ์ฉ์๋ง ํ์ฑํํ ์ ์๋๋ก ๊ตฌํ
# tweet/views.py
from django.contrib.auth.decorators import login_required
@login_required
def delete_tweet(request, id):
my_tweet = TweetModel.objects.get(id=id)
my_tweet.delete()
return redirect('/tweet')
- urls.py ์์ ์ญ์ ๊ธฐ๋ฅ ํจ์๋ฅผ ์ฐ๊ฒฐ : <int:id> ๊ฒ์๊ธ์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ์ฌ์ฉ
# tweet/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('tweet/', views.tweet, name='tweet'),
path('tweet/delete/<int:id>', views.delete_tweet, name='delete-tweet'),
]
- home.html ์ ๊ธ ์ญ์ url ์ ์ฐ๊ฒฐ : ์ญ์ ๋ฒํผ์ /tweet/delete/tw.id ๋ก ์ฐ๊ฒฐ์ด ๋๋๋ฐ, ์ด tw.id๋ ๊ฒ์๊ธ์ ๊ณ ์ id๊ฐ
<!-- templates/tweet/home.html -->
... ์๋ต
<!-- ์์ฑ ๋ ๊ธ์ด ๋์ค๋ ๊ณณ -->
<div class="row">
{% for tw in tweet %}
<div class="col-md-12 mb-2">
<div class="card">
<div class="card-body">
{% if tw.author == user %}
<div style="text-align: right">
<a href="/tweet/delete/{{ tw.id }}">
<span class="badge rounded-pill bg-danger">์ญ์ </span>
</a>
</div>
{% endif %}
<div style="text-align: right">
<a href="#">
<span class="badge rounded-pill bg-success">๋ณด๊ธฐ</span>
</a>
</div>
<div class="media">
<div class="media-body">
<h5 class="mt-0">{{ tw.content }}</h5>
</div>
<div style="text-align: right">
<span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} ์ </span>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
... ์๋ต
์ถ์ฒ ์คํ๋ฅดํ์ฝ๋ฉํด๋ฝ
'๐ฆ ๋ด์ผ๋ฐฐ์์บ ํ > TIL(Today I Learned)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TIL_220613_ํ ํ๋ก์ ํธ django (0) | 2023.01.01 |
---|---|
TIL_220602_ํ ํ๋ก์ ํธ Django (0) | 2023.01.01 |
TIL_220527_Django ๊ธฐ์ด (0) | 2023.01.01 |
TIL_220526_Django ๊ธฐ์ด (0) | 2023.01.01 |
TIL_ํ ํ๋ก์ ํธ_KPT (0) | 2023.01.01 |
์์คํ ๊ณต๊ฐ ๊ฐ์ฌํฉ๋๋ค