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를 채운다. - bootstrap introduction
- bootstrap form
form
의 경우 입력을 받아 서버에 전달(POST)토큰 코드
를 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>
- 중간의 `` 는 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파일에서 ``의 형태로 들어감) 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),
]
- 로그인 후에 어떻게 될지는 다음에 하도록 함(기본적인 뼈대만 만들은 상태)