20210202_ Django admin, template,view만들기, url연결 - 회원가입, 로그인
Django
Django admin
기본적으로 admin의 경우
settings.py
를 통해 활성화 되어 있다.또한
urls.py
의 경우에도 admin은 기본적으로 만들어져 있다.url주소에 admin을 붙이면 관리자 창을 이용할 수 있다.
python manage.py runserver
를 통해서 서버를 돌리고 해당 ip주소로 들어가면 홈페이지가 뜬다.해당 ip주소에
/admin
을 넣으면 관리자 로그인 화면이 뜬다.서버 종료는
ctrl + c
로그인을 위해서 계정을 만들어야 하는데
python manage.py createsuperuser
를 통해 만들수 있다.- 이를 통해서 로그인 하면 개발자 툴 페이지로 접근 가능하다.
Django admin 활용
앱에서 만든 모델 어드민에 등록
admin.py
파일에 관리자가 사용할 정보를 넣을 수 있음
from django.contrib import admin
from .models import Sl_user
# Register your models here.
class Sl_userAdmin(admin.ModelAdmin):
pass
admin.site.register(Fcuser, FcuserAdmin)
- 저장후 runserver 시 모델이 들어간것을 볼 수 있고 모델 수정삭제를 Sql로 작성해야 하나 관리자 도구를 통해 유저 인터페이스 내에서 가능함
시각화 개선
인터페이스 내에서 생성된 앱안에 오브젝트가 무엇인지 알아보기 힘듦(그냥 단지 앱이름의 object로만 뜨기 때문에 각 오브젝트의 username을 반환시켜 알아보기 편하게 만들어야 함)
__str__
을 통해서 객체를 문자열로 반환하게 만든다.models.py
파일
from django.db import models
# Create your models here.
class Sl_user(models.Model):
username = models.CharField(max_length=32, 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
class Meta:
db_table = 'slowbuscamp_user'
이것 보다 더 보기 좋게 하기 위해 각 오브젝트의 필드와 내용이 보이게 하려면
admin.py
파일
from django.contrib import admin
from .models import Sl_user
# Register your models here.
class Sl_userAdmin(admin.ModelAdmin):
list_display = ('username', 'password')
admin.site.register(Fcuser, FcuserAdmin)
관리자 탭에서의 보여지는 테이블 이름 변경
models.py
파일class Meta
에서 관리자 탭 db테이블 이름변경 가능
from django.db import models
# Create your models here.
class Sl_user(models.Model):
username = models.CharField(max_length=32, 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
class Meta:
db_table = 'slowbuscamp_user'
verbose_name = '슬로우버스캠프 사용자' # 기본적으로 복수형을 지원하기 때문에 s가 자동으로 붙게 되어 있음
verbose_name_plural = '슬로우버스캠프 사용자' # 복수형이름을 따로 지정하여 자동으로 붙는 s를 제거 가능
회원가입 구현
1. Django template 만들기
표시될 회원가입 html 만들기
기본적으로 bootstrap에서 제공하는
form
,CSS
,JS
기본 형식을 가져다 쓴다. 전체적인 형식은starter template
을 참고하여 head를 만들고 form 형식을 가져다가 body를 채운다.form
의 경우 입력을 받아 서버에 전달(POST){% csrf_token %}
를form
안에 넣어 놓으면 암호화 키를 숨겨두어 크로스 도메인을 막아줌(django에서는 토큰 없으면 에러남)- 크로스 도메인은 다른 사이트에서 서버에 데이터 요청시 보안정책으로 SOP 동일 근원정책으로 회신 받지 못하는 것을 말함
CDN(콘텐츠 배달 네트워크)
- 로컬이 아닌 css,html,js를 제공하는 서비스의 서버 원본에서 가져오는 것이 아니라 현재 pc에서 가장 빠르게 가져올수 있는 위치의 서버에서 요청하여 가져오게됨
- 성능을 높이기 위해서 사용함(bootstrap에서 아까 연결하였음)
Static 폴더
- css, js 등의 파일을 로컬에 넣어 놓고 연결시킴
- bootstrap 4.3 theme free 키워드 검색 한 결과의 한 사이트
- 사이트를 통해서 마음에 드는 스타일의
bootstrap.min.css
다운 받는다. 물론,bootstrap.css
도 상관 없다. min은 압축용어라고 한다. - 프로젝트 폴더에 static 폴더 생성하여 해당 파일을 넣고 프로젝트
settings.py
에서 맨아래 STATIC_URL에서 STATICFILES_DIRS = [] 을 설정함
"setttings.py 파일"
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
] # BASE_DIR 이 프로젝트 폴더를 의미, 프로젝트 폴더의 static 폴더
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> -->
<!-- bootstrap에서 다운받은 stylesheet 를 연결시켜 적용 -->
<link rel="stylesheet" href="/static/bootstrap.min.css" />
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js" integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js" integrity="sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="row mt-5">
<div class="col-12 text-center">
<h1>회원가입</h1>
</div>
</div>
<div class="row mt-5">
<div class="col-12">
<!-- 에러처리 -->
{{error}}
</div>
</div>
<div class="row mt-5">
<div class="col-12">
<form method="POST", action=".">
<!-- 토큰 -->
{% csrf_token %}
<div class="form-group">
<label for="username" class="form-label">사용자 이름</label>
<input type="text" class="form-control" id="username" placeholder="사용자 이름" name="username">
</div>
<!-- name 속성을 사용하여 서버에서 읽을수 있게함 -->
<div class="form-group">
<label for="useremail" class="form-label">사용자 이메일</label>
<input type="email" class="form-control" id="useremail" placeholder="사용자 이메일" name="useremail">
</div>
<div class="form-group">
<label for="password" class="form-label">비밀번호</label>
<input type="password" class="form-control" id="password" placeholder="비밀번호" name="password">
</div>
<div class="form-group">
<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>
</div>
</div>
</div>
</body>
</html>
- 중간의
{{error}}
는 POST 요청시에 오류처리만을 보여주기 위한 시각적 개선안으로 사용된다. (없으면 사이트 전체가 바뀌기 때문에 인터페이스적으로 불편) - HTTP Method(서버에 요청하는 방식) :
POST
VSGET
GET
: 어떠한 정보를 가져와 조회하기 위해서 사용- URL데이터 노출O / 데이터의 위치 헤더 / 캐싱 가능
htt://localhost:8080/boardList?name=제목&contents=내용
POST
: 데이터를 서버로 제출하여 추가 또는 수정하기 위해서 사용- URL데이터 노출X / 데이터의 위치 바디/ 캐싱 불가
http://localhost:8080/addBoard
- 참고 사이트
2. Django views 만들기
- 해당 앱의
views.py
파일에서 구현할 로직과 데이터 베이스 연결 지정 - 필요한 기능을 위한 import먼저하고 함수를 선언할때
request
객체로 선언해야함 request
객체 : 클라이언트에서 서버로 보내는 요청을 담고 있는 객체Django shortcut functions
-render()
랜더 메서드 : 해당 파일을 렌더링함- 모양 및 옵션 :
render(request, template_name, context=None, content_type=None, status=None, using=None)
- 눈여겨 볼 옵션
context
: dictionary 형태의 변수이름을 옵션에 넣으면 그 변수안에 들어 있는 key 와 value를 연결시켜 렌더링함 (key의 경우 html파일에서{{key}}
의 형태로 들어감) HttpRequest
객체의 경우 여러가지 속성을 가지고 있는데 그중HttpRequest.method
메서드의 경우 HTTP 메서드가 어떤 형식으로 오느냐를 가지고 수행할 명령을 지정가능하다. (GET , POST에 따라서)- POST를 받은 값을 할당할 변수 선언시 get을 통해 값이 없을 경우 예외 처리
- 마지막으로 model 인스턴스인 sl_user의
save
함수를 통해서 DB로 INSERT SQL 전달
from django.http import HttpResponse
from django.shortcuts import render
from django.contrib.auth.hashers import make_password, check_password
# 저장된 password 암호화
from .models import Fcuser
def register(request): # request 형태로 전달해줘야 되고
if request.method == 'GET':
# 반환하고 싶은 html파일, 폴더를 포함하면 경로 모양으로
return render(request, 'register.html')
elif request.method == 'POST':
# username = request.POST['username'] # 값을 못받고 제출시 오류가 나기 때문에 예외 처리 필요
# password = request.POST['password']
# re_password = request.POST['re-password']
username = request.POST.get('username', None)
useremail = request.POST.get('useremail', None)
password = request.POST.get('password', None)
re_password = request.POST.get('re-password', None)
res_data = {}
if not (username and useremail and password and re_password): # 값을 못받는 경우 에러시 에러출력 메세지
res_data['error'] = '모든 값을 입력해야 합니다.'
elif password != re_password:
res_data['error'] = '비밀번호가 일치하지 않습니다!'
# return HttpResponse('비밀번호가 일치하지 않습니다!')
else:
sl_user = Sl_user(
username=username,
useremail=useremail,
password=make_password(password) # 암호화 함수를 사용해서 암호화 하여 생성
)
sl_user.save()
return render(request, 'register.html', res_data)
# 들어오는 방법이 2가지임, 직접 주소를 작성하는 경우 및 등록버튼을 눌러서 보내는 경우
3. Django urls 연결하기
- 프로젝트 폴더
urls.py
에 앱 연결 (주소창에 적을때 어떻게 연결할지 정해주는 것임) - 기존의 admin 연결과 같이 path경로 설정해줌
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('sl_user/', include('sl_user.urls'))
]
주소창에 도메임 이름 이후에 오는
자원 경로
설정 ->sl_user/
이라고 치면sl_user
라는 앱의 urls 파일로 연결앱 자체에 urls 파일 생성
urls.py
-> views의 해당 함수와 연결시키기
from django.urls import path
from.import views
urlpatterns = [
path('register/', views.register),
]
로그인 구현
1. Django template 만들기
- register html에서 필요 없는 부분을 제거하고, 제목 로그인으로 변경
- username , password 만 남기고 버튼은 로그인으로 변경
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> -->
<!-- bootstrap에서 다운받은 stylesheet 를 연결시켜 적용 -->
<link rel="stylesheet" href="/static/bootstrap.min.css" />
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js" integrity="sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js" integrity="sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="row mt-5">
<div class="col-12 text-center">
<h1>로그인</h1>
</div>
</div>
<div class="row mt-5">
<div class="col-12">
{{error}}
</div>
</div>
<div class="row mt-5">
<div class="col-12">
<form method="POST", action=".">
{% csrf_token %}
<div class="form-group">
<label for="username" class="form-label">사용자 이름</label>
<input type="text" class="form-control" id="username" placeholder="사용자 이름" name="username">
</div>
<div class="form-group">
<label for="password" class="form-label">비밀번호</label>
<input type="password" class="form-control" id="password" placeholder="비밀번호" name="password">
</div>
<button type="submit" class="btn btn-primary">로그인</button>
</form>
</div>
</div>
</div>
</body>
</html>
2. Django views 만들기
- 기존의 앱에
login
함수 만듦 - 기존
register
와 다른 점은 거의 없으나Sl_user.objects.get
을 사용하여 db에서 username이 같은 것만 sl_user에 할당하여 모델을 가져오고,make_password
된 sl_user의 password를check_password
를 통해 입력받은 password와 같은지 확인
from django.http import HttpResponse
from django.shortcuts import render
from django.contrib.auth.hashers import make_password, check_password # 저장된 password 암호화
from .models import Fcuser
# Create your views here.
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
username = request.POST.get('username', None)
password = request.POST.get('password', None)
res_data = {}
if not (username and password):
res_data['error'] = '모든 값을 입력해 주세요.'
else:
sl_user = Sl_user.objects.get(username=username)
if check_password(password, sl_user.password):
# 로그인 처리
pass
else:
res_data['error'] = '잘못된 아이디 또는 비밀번호 입니다.'
return render(request, 'login.html', res_data)
3. Django urls 연결하기
login/
입력시 views의login
함수와 연결되게 설정
from django.urls import path
from.import views
urlpatterns = [
path('register/', views.register),
path('login/', views.login),
]
- 로그인 후에 어떻게 될지는 다음에 하도록 함(기본적인 뼈대만 만들은 상태)