파이썬 장고 실무 기초 3주차 1~9강
우리가 만든 User모델 업그레이드 하기
bio = models.CharField(max_length=256, default='')
models.Model 자리에 AbstractUser를 사용
상속받듯이 기존 데이터베이스에 없던 속성만 추가해서 생성
#user/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class UserModel(AbstractUser): # UserModel에서 AbstractUser(장고기본유저모델)를 사용하겠다
class Meta:
db_table = "my_user" # 여기는 테이블 이름이에요! 꼭 기억 해 주세요!
#기본 모델에 없던 것만 추가
bio = models.CharField(max_length=256, default='')
setting.py 맨 밑에 코드 추가
# mySpartaSns/settings.py
AUTH_USER_MODEL = 'user.UserModel'
AUTH_USER_MODEL 이라는 변수에 'user.UserModel' 👉 기본 인증과정 (AUTH_USER_MODEL)을 user앱에 작성한 UserModel로 사용하겠다
User모델을 데이터베이스에 적용시키기
python manage.py makemigrations
python manage.py migrate
Django의 사용자 모델을 적용하기 - 회원가입 수정하기
👉 Django에서 제공하는 사용자모델로 회원가입 기능을 수정
AUTH_USER_MODEL = 'user.UserModel' 이 기본 모델
user앱의 views.py를 수정 sign_up_view() 함수
# user/views.py
from django.contrib.auth import get_user_model #사용자가 있는지 검사하는 함수
def sign_up_view(request):
if request.method == 'GET':
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') # 회원가입이 완료되었으므로 로그인 페이지로 이동
render 함수 : Django에서 HTML 파일과 뷰 함수를 연결하여 사용자에게 HTML 페이지를 반환하는 함수
render(HTTP 요청 객체(request), 템플릿 파일 이름(template_name) , 컨텍스트(context) : 템플릿에서 사용되는 변수를 지정)
Django의 사용자 모델을 적용하기 - 로그인 수정하기
로그인 기능 👉 sign_in_view 함수
# user/views.py
from django.contrib import auth # 사용자 auth 기능
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 HttpResponse("로그인 성공")
else:
return redirect('/sign-in') # 로그인 실패
elif request.method == 'GET':
return render(request, 'user/signin.html')
from django.contrib import auth 장고에서 제공하는 기능 - 비밀번호 체크, 로그인 기능
로그인 이후 기능 다듬기 - 로그인 후 페이지 이동하기
- 로그인 후 이동 페이지 만들기
templates > tweet > home.html
- 이동 페이지 연결하기
새로 만든 home.html을 연결할 url과 view를 연결
페이지를 연결 할 때에 공통적으로
views.py 👉 render() 함수
views.py 함수 👉 urls.py 에 연결
새로 만든 페이지는 글쓰기 주요 기능이 들어 갈 페이지이기 때문에 tweet 앱에 연결한다.
view 연결하기
# 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')
home 함수 - 사용자가 인증되어있는지 여부에 따라 다른 URL로 리다이렉션
즉, GET 요청이 없기 때문에 HTTP 요청(request)을 렌더링하지 않는다.
user = request.user.is_authenticated 👉 장고가 제공하는 사용자 모델을 사용 했을 때 쓸 수 있는 함수 (사용자 로그인 여부)
url 연결하기
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 함수(tweet/home.html을 화면에 띄워주는 역할) 연결
]
mySpartaSns > urls.py 파일에 등록
user앱의 views.py 동작 수정하기
http://127.0.0.1:8000/tweet 주소로 잘 가게 설정 해 주어야 한다.
로그인 👉 user앱의 sign_in_view() 실행
저 부분을 return redirect('/') 로 변경하면, 로그인했을 때 '로그인 성공' 창 대신에 홈 화면으로 넘어가게 된다.
짜잔~
로그인 이후 기능 다듬기
로그인 후에 화면에 사용자 정보 나타내고 로그인/회원가입 네비게이션 바 숨기기
사용자 정보 나타내기
templates > tweet > home.html
<!-- templates/tweet/home.html -->
<!-- 왼쪽 컬럼 -->
<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>
로그인/회원가입 네비게이션 바 숨기기
templates > base.html을 열어주세요! 여기에서 Sign In, Sign Up 부분을 고쳐 보려고 합니다.
<!-- 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 %} <!-- if문 종료 -->
</form>
템플릿 문법
{{ 변수 }}
{% if문 %}
https://goodthings4me.tistory.com/92
로그인 필요 기능과 로그아웃 만들기
로그아웃 기능 - 1) 로그아웃 후에 이동 할 화면 2) 로그인 후 이동 할 화면
1. 로그인 한 사람만 페이지에 접근 가능하게 만들기
twee > views.py
tweet 함수에 로그인 한 사용자를 판단하는 기능을 추가
# tweet/views.py
from django.shortcuts import render, redirect
def tweet(request): # tweet 앱의 home.html 보여주기
if request.method == 'GET':
user = request.user.is_authenticated # 사용자가 인증을 받았는지 (로그인이 되어있는지) - 로그인 된 사람만 보여주기
if user: # 로그인 한 사용자라면
return render(request, 'tweet/home.html')
else: # 로그인이 안 되어있으면
return redirect('/sign-in')
tweet() 함수 - GET 요청이 발생할 때 render() 함수를 사용하여 'tweet/home.html' 템플릿을 로드한다.
render(HTTP 요청 객체(request), 템플릿 파일 이름(template_name) 및 컨텍스트(context))
request.user.is_authenticated 👉 사용자 로그인 여부를 나타내는 불리언 값 반환
tweet() 함수에서 이 값을 사용 - 사용자가 로그인되어 있지 않은 경우 'sign-in' URL로 리다이렉트 👉 request 필요
2. 로그인 한 사람은 사용 안 해도 되는 페이지 기능 만들기
로그아웃 구현하기
user > views.py
#user/views.py
from django.contrib.auth.decorators import login_required
@login_required
def logout(request):
auth.logout(request) # 인증 되어있는 정보를 없애기
return redirect("/")
`@login_required `user = request.user.is_authenticated` 모두 로그인 한 사람들만 사용 할 수 있도록 도와주는 기능
@login_required 로그인 하지 않으면 접근이 불가능 하게 만드는 기능
request.user.is_authenticated 로그인의 여부만 검증 해 주는 기능
user > urls.py 로그아웃 url 추가
# 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의 '로그아웃' 부분을 추가
<a class="nav-link" href="/logout"> 로그아웃 </a>
GitHub 댓글