장고의 MVT 패턴을 기억하면서
찬찬히 실제 코드를 작성해보자.
Django로 새프로젝트를 생성하면
자동 생성되는 파일들이 있다.
SNS구현을 하려면 기능은 크게 3가지가 필요하다.
1. 사용자관리(회원가입, 로그인, 로그아웃)
2. 글쓰기(삭제, 수정, 댓글)
3. 친구만들기(follow)
사용자와 글이라는 App을 생성하여
정보를 관리하면 좋을 것 같다.
01. APP 생성하기
터미널에서 아래 코드를 실행하면 App이 생성된다.
django-admin startapp 만들고자하는app이름
user와 tweet이라는 앱을 차례로 만들어주고
user앱은 사용자관리를 담당하고
tweet앱은 글관리를 담당하게 전체적인 방향을 정한다.
새로운 App을 생성하면
반드시 settings.py의 INSTALLED_APPS에
만든 앱을 추가해야 관리할 수 있는 상태가 된다.
(앱 이름으로 추가)
02. 데이터베이스 연결
앱을 생성하고 run(실행)버튼을 클릭하면
db.sqlite3 파일이 생성된다.
데이터베이스 추가 - 경로 데이터 설정 - db.sqlite3 파일 클릭
- 테스트 한 후 이상 없다면 연결이 잘 된 것이다.
연결 후 화면은 아래와 같다.
03. 모델만들기
생성된 App의 models.py 에서 모델을 생성한다.
모델은 데이터 유형을 지정하여 DB에서 인지할 수 있도록 한다.
아래는 user App의 models.py 를 구성하는 예시이다.
#user/models.py
# models를 가져온다.
from django.db import models
# Create your models here.
# UserModel이라는 이름으로 모델을 생성한다.
class UserModel(models.Model):
class Meta:
db_table = "my_user"
username = models.CharField(max_length=20, null=False)
password = models.CharField(max_length=256, null=False)
bio = models.CharField(max_length=256, default='')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
DB에 저장될 table 의 이름을 my_user라고 정하고
Meta class 안에 정보를 담는다.
데이터의 유형에 따라 field를 다르게 지정해야
정상적으로 데이터가 저장된다.
이렇게 새로운 모델을 생성하면
데이터베이스에 넣어주는 작업이 필요하다.
터미널을 열고 아래 코드를 차례로 작성한다.
python manage.py makemigrations
python manage.py migrate
코드를 실행하면 DB의 table에 아래와 같이
my_user가 생성되고 그 안의 값들은 모델에 지정해준대로
설정이 된다.
04. Admin(관리자) 페이지
Super user를 생성해야 admin 페이지에 접근 가능하다.
run(실행)상태라면 중지버튼을 꼭 클릭하고 생성한다.
그렇지 않으면 에러메세지가 출력될 것이다.
터미널에서 아래 코드로 슈퍼유저를 생성하면,
유저정보를 입력하라는 메세지가 뜬다.
python manage.py createsuperuser
차례로 입력하면 생성되고,
장고를 실행시키고
http://127.0.0.1:8000/admin 로 접속하여
Super user 정보를 입력하면 관리자 화면이 뜬다.
장고에서 기본적으로 제공하는 모델들이 보인다.
현재 user App의 models.py에서 생성한 모델은 Admin 페이지와
연결하지 않았기 때문에 보이지 않는다.
user의 Admin.py를 세팅한다.
from django.contrib import admin
from .models import UserModel
# Register your models here.
admin.site.register(UserModel)
모델을 등록하면 아래와 같이 User models가 추가된 것을 확인 할 수 있다.
05. tweet 모델생성
tweet App의 models.py에 아래코드를 입력한다.
# tweet/models.py
# DB의 models를 불러온다.
# UserModel을 가져온다.(foreignKey로 사용됨)
from django.db import models
from user.models import UserModel
# Create your models here.
class TweetModel(models.Model):
class Meta:
db_table = "tweet"
author = models.ForeignKey(UserModel, on_delete=models.CASCADE)
content = models.CharField(max_length=256)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
ForeignKey는 외부모델을 가져와서 사용하는 방식이다.
UserModel의 author정보를 가져온다.
(글 작성의 경우 회원가입한 user만 작성할 수 있기 때문에)
모델을 새로 생성하면 데이터베이스에 알려줘야 등록이 된다.
데이터베이스에 모델을 등록하는 코드는 위의 내용 참고!
모델이 등록되면 Admin 페이지에 연결해주어야 관리가 가능하다.
Admin 페이지에 연결하는 admin.py를 작성하는 코드는
위의 내용과 동일하다.
연결이 완료되면 아래와 같이 Tweet models가 추가된 것을 확인할 수 있다.
여기까지 작업을 하면
Admin 페이지에서 user정보와 tweet 정보를 관리할 수 있는 상태가 된다.
그럼 각 App의 정보는 어디서 받아올까?
html의 input태그 안에 입력된 내용을 받아와야 한다.
06. 회원가입, 로그인페이지 구현
template 폴더에 html을 작성하고
urls.py를 작성하여 url을 연결한다.
url을 왜 연결해줘야 할까?
아래와 같이 우리가 웹상에서 url 주소를 작성하면
메인 App에서 urls.py안에 연결된 각 App의 url을 찾아
그 페이지(html)를 보여줄 수 있게 되기 때문이다.
어떻게 url을 연결해주어야 할까?
App의 views.py의 함수를 작성하여
데이터를 받거나(POST) html을 보여주고(GET)
App의 urls.py에서 path를 연결해준다.
06-1) 회원가입기능(sign-up)
views.py에서 sign-up 함수를 생성하고
GET방식으로 화면을 보여주고, POST방식으로 정보를 DB에
보내주도록 코드를 작성한다.
# render로 html을 출력할 수 있다.
# UserModel을 불러온다.
from django.shortcuts import render, redirect
from .models import UserModel
def sign_up_view(request):
if request.method == 'GET': # GET 메서드로 요청이 들어 올 경우
return render(request, 'user/signup.html')
elif request.method == 'POST': # 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 = UserModel.objects.filter(username=username)
if exist_user:
return render(request, 'user/signup.html') # 사용자가 존재하기 때문에 사용자를 저장하지 않고 회원가입 페이지를 다시 띄움
else:
new_user = UserModel()
new_user.username = username
new_user.password = password
new_user.bio = bio
new_user.save()
return redirect('/sign-in')
GET 방식으로는 작성된 signup.html을 보여주도록하고
POST 방식으로는 html의 form 태그 안에 있는
input 태그의 name 속성값으로 정보를 받아온다.
위의 코드에서는
작성한 pw와 재작성한 pw를 비교하여 같지 않거나
이미 DB에 존재하는 username을 작성했을때
페이지가 reload 하도록 하였다.
reload 되는 상황이 아니라면
UserModel 클래스에
new_user의 정보를 등록할 수 있도록하고
등록한 정보를 save()로 저장하면
로그인 페이지로 연결되도록 하였다.
다음은 views.py와 정보를 받아올 html을
맞춰주는 작업이 필요하다.
작업은 form 태그안에서 이루어지고
form 태그의 method 속성으로 get or post 방식을 지정하고,
action 속성으로 urls.py에 연결할 path를 작성한다.
input 태그의 name 속성값을 views.py와 맞춰준다.
{% csrf_token %} 을 반드시 입력하여 암호화한다.
<form class="form-area" method="post" action="/sign-up/">
{% csrf_token %}
<div class="form-group mt-2 mb-2">
<label for="username">이름</label>
<input type="text" class="form-control" id="username" name="username">
</div>
<div class="form-group mt-2 mb-2">
<label for="password">비밀번호</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<div class="form-group mt-2 mb-2">
<label for="password2">비밀번호 확인</label>
<input type="password" class="form-control" id="password2" name="password2">
</div>
<div class="form-group mt-2 mb-2">
<label for="bio">나를 한마디로</label>
<input type="text" class="form-control" id="bio" name="bio">
</div>
<hr>
<div style="float: right">
<button type="submit" class="btn btn-primary">회원가입</button>
<a href="/sign-in" class="btn btn-secondary">로그인 페이지로</a>
</div>
</form>
이제는 urls.py에서 위에 작성한 html의 path를 지정해준다.
from django.urls import path
from . import views
urlpatterns = [
path('sign-up/', views.sign_up_view, name='sign-up'),
]
마지막으로, 메인 App의 urls.py에 App의 urls.py를 연결해준다.
include를 import하여 작성한다.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('user.urls'))
]
06-2) 로그인기능(sign-in)
기능을 구현하는 방법은 회원가입페이지와 동일하지만
세션(session)으로 사용자의 정보를 저장하는 부분이 다르다.
App의 views.py를 아래와 같이 작성한다.
from django.shortcuts import render, redirect
from .models import UserModel
from django.http import HttpResponse
def sign_in_view(request):
if request.method == 'POST':
username = request.POST.get('username', None)
password = request.POST.get('password', None)
me = UserModel.objects.get(username=username) # 사용자 불러오기
if me.password == password: # 저장된 사용자의 패스워드와 입력받은 패스워드 비교
request.session['user'] = me.username # 세션에 사용자 이름 저장
return HttpResponse(me.username)
else: # 로그인이 실패하면 다시 로그인 페이지를 보여주기
return redirect('/sign-in')
elif request.method == 'GET':
return render(request, 'user/signin.html')
POST방식으로 받아온 username과
UserModel에 저장되어있는 username이 같은 정보를 불러오고
불러온 정보 안의 pw와 POST방식으로 받아온 pw를 비교하여
같다면 session에 사용자 이름을 저장해두었다가 HttpResponse로
화면에 출력해준다.
마찬가지로 html을 views.py와 맞추어주고,
urls.py에 path를 연결해주면 로그인기능이 완성된다.
그런데, 이미 Django에서는 위에서 만든 기능을
더 간편하게 구현할 수 있도록 하는 모듈이 존재한다.
그 모듈은 어떻게 사용할 수 있는지,
다음 글에서 알아보자💛