Django 간단한 페이지 만들기

이민기·2022년 5월 30일
0
post-thumbnail

APP 생성해 주기

$ django-admin startapp user
$ django-admin startapp tweet

프로젝트 구조 세팅

settings.py에 앱생성후 생성한 앱을 추가해 준다.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    **'tweet',**
    **'user',**
]

ORM 알아보기

ORM (Object Relational Mapping) 은 데이터베이스를 하나의 '객체(Object)' 덩어리로 보고, 데이터베이스를 SQL언어가 아닌 클래스로 쉽게 표현 및 사용 할 수 있게 해 줍니다.

class myBakery:
    bread_type = ''  # 빵의 종류
    bake_time = ''  # 굽는 시간
    price = 0  # 가격

위와 같은 클래스를 데이터베이스의 형태로 만들어서 사용 하려고 합니다

클래스 이름과 내부에 선언 된 변수들이 '비슷한 성격'들을 가지고 있죠~? 우리가 ORM 모델을 만들 때에도 마찬가지로 어떤 역할을 하는 모델을 생성 할 것인지, 어떤 요소들을 담을것인지 고민이 필요합니다!

직접 만들어 보면서 적용 해 볼까요~?

User Model

Django는 기본적으로 User모델을 제공합니다. 사용자의 관리와 로그인/로그아웃이 이미 다 구현이 되어있어요! 하지만 우리가 직접 먼저 만들어본 후에 Django에서 제공하는 모듈을 사용하려고 합니다!

django의 user앱 아래의 models.py에 작성 해 볼게요!

#user/models.py
from django.db import models

# Create your models here.
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)

위의 모델 클래스에서 class Meta 는 이 모델의 정보를 담고있습니다. 여기에서는 테이블 이름만 정해주었습니다

그리고 django에서 제공하는 models를 사용해서 각 요소에 어떤 데이터의 형식이 들어갈 지 정해주고, 각 필드에 제한을 두었어요.

모델 데이터베이스에 넣기

방금 우리가 열심히 만든 User Model을 데이터베이스에 넣어주려고 합니다! 두 단계로 나눌 수 있어요. '데이터베이스 변경을 알려주는 명령어''변경된 데이터베이스를 반영 해 주는 명령어' 로 나누어집니다.

데이터베이스 변경을 알려주는 명령어 makemigrations

python manage.py makemigrations

변경 된 데이터베이스를 적용시켜주는 migrate

python manage.py migrate

user.0001_initial이라고 보이네요! 이게 우리가 user앱에서 만든 모델이 적용되었다는 얘기입니다!

Django Admin

장고는 우리가 코드를 많이 작성하지 않고도 사용 할 수 있도록 이미 많은 기능이 구축되어 있습니다.

대표적인 예가 바로 'Admin'이에요.

장고 서버를 실행시켜주고, http://127.0.0.1:8000/admin 으로 접속 해 주세요

Createsuperuser

python manage.py createsuperuser

그리고 아까 우리가 만들어준 UserModel을 넣어 주려고 해요! 다음과 같이 코드를 입력 해 주세요!

아래의 코드를 user의 admin.py에 붙여넣어 주세요

from django.contrib import admin
from .models import UserModel

# Register your models here.
admin.site.register(UserModel) # 이 코드가 나의 UserModel을 Admin에 추가 해 줍니다

이제 다시 장고 Admin 페이지로 가서 새로고침을 해 주면 UserModel이 들어가 있는 것을 볼 수 있어요!

TweetModel

SNS 게시글은 작성자, 내용, 글 생성일자, 수정일자 정도 있으면 좋을 것 같아요!

tweet앱의 models.py로 들어가서, 아래의 코드를 넣어주세요.

# tweet/models.py
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는 '외부 모델을 가져와서 사용하겠다.' 라는 얘기에요.

author = models.ForeignKey(UserModel, on_delete=models.CASCADE)

author는 새로운 사람이 아니라, 아까 우리가 만들어 주었던 User Model의 사용자가 작성 한 글 이기 때문에 ForeignKey를 사용해서 넣어주었습니다.

마찬가지로 데이터베이스 마이그레이션 마이그레이트 해주고, admin안에 db도 넣어 주세요!

HTML 템플릿

우선 우리의 프로젝트 탐색기에서, templates 폴더 아래에 다음과 같이 파일들을 만들어주세요!

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %} | spartaSNS</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
            crossorigin="anonymous"></script>
    <style>
				.title-center {
            text-align: center;
            margin-top: 50px;
        }

        .wrap {
            width: 400px;
            margin: 0 auto;
        }

        .form-area {
            margin-top: 25px;
        }

        .timeline-container {
            margin-top : 25px
        }
    </style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container">
        <a class="navbar-brand" href="/">SpartaSNS</a>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item active">
                    <a class="nav-link" href="#"> 친구 <span class="sr-only"></span></a>
                </li>
            </ul>
        </div>
        <form class="form-inline my-2 my-lg-0">
            <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>
        </form>
    </div>
</nav>
{% block content %}

{% endblock %}

</body>
</html>

signup.html

{% extends 'base.html' %}

{% block title %}
    회원가입
{% endblock %}
{% block content %}
    <div class="container">
        <div class="wrap">
            <h2 class="title-center"> 회원가입 </h2>
            <form class="form-area">
                <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>

        </div>
    </div>
{% endblock %}

signin.html

{% extends 'base.html' %}

{% block title %}
    로그인
{% endblock %}
{% block content %}
    <div class="container">
        <div class="wrap">
            <h2 class="title-center"> 로그인</h2>
            <form class="form-area">
                <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>
                <hr>
                <div style="float: right">
                    <button type="submit" class="btn btn-primary">로그인</button>
                    <a href="/sign-up" class="btn btn-secondary">회원가입 페이지로</a>
                </div>
            </form>

        </div>
    </div>
{% endblock %}

URL 연결 기본파일

# mySpartaSns/urls.py
from django.contrib import admin
from django.urls import path, **include**

urlpatterns = [
    path('admin/', admin.site.urls),
    **path('', include('user.urls'))**
]

VIEWS 연결

from django.shortcuts import render

# Create your views here.
def sign_up_view(request):
    return render(request, 'user/signup.html')

def sign_in_view(request):
    return render(request, 'user/signin.html')

URL 연결

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'),
]

회원가입

from django.shortcuts import render, **redirect
from .models import UserModel**

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:
            new_user = UserModel()
            new_user.username = username
            new_user.password = password
            new_user.bio = bio
            new_user.save()
        return redirect('/sign-in')**

html의 input에 입력 했던 친구들은 각각 username, password, password2, bio로 sign_up_view()함수로 들어가게 됩니다!

html에서 넘겨준 데이터를 views.py에서 받아줍니다.

password와 password2가 일치하는지 확인 해 주고, 일치하면 저장 해 줍니다.

user앱의 views.py의 sign_up_view함수에 아래와 같이 추가 해 주겠습니다.

redirect 함수를 이용해서, 저장 완료 되었다면 로그인 페이지 인 /sign-in url로 이동 하게 해 줍니다.

로그인

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 = UserModel.objects.get(username=username)  # 사용자 불러오기
        if me.password == password:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교
            request.session['user'] = me.username  # 세션에 사용자 이름 저장
            return HttpResponse("로그인 성공!")
        else: # 로그인이 실패하면 다시 로그인 페이지를 보여주기
            return redirect('/sign-in')
    elif request.method == 'GET':
        return render(request, 'user/signin.html')

username, password가 /sign-in으로 전달 되기 때문에, 'sign_in_view'함수가 실행이 됩니다.

user앱의 sign_in_view 함수에 로그인 기능들을 추가 해 볼게요~! 위에서 말했던 '세션'기능을 사용하려고 해요!

username과 password를 검사 하기 위해서는 '사용자'를 불러와야합니다.

UserModel을 사용해서 사용자를 불러오는 작업을 해 볼게요!

profile
지나가는사람

0개의 댓글