Django

Django 기초 2주차_Sparta Coding Club

끈끈 2023. 4. 4. 14:55

 

2주차에서 배울 것

  • Django를 실행시키고 관리하기 위한 명령어를 알아봄
  • Django의 ORM을 알아보고 Database와 연동하여 사용해 봄
  • Admin의 기능을 알아봄
  • 사용자 모델을 만들고 사용자 관리 기능을 구현해 봄

 


 

vs code에서 장고 사용하기

  • python -m venv venv
  • venv\Script\Activate
  • pip install django
  • python -m django --version (버전 확인)
  • django-admin startproject [프로젝트명]
  • python manage.py runserver (서버 실행)

 


 

프로젝트 구조 만들기

 

필요한 기능

 

  • 사용자 관리 (회원가입 / 로그인 / 로그아웃)
  • 글 쓰기
  • 친구 만들기

 

django-admin startapp user # 사용자 관리 (회원가입/로그인/로그아웃) 담당
django-admin startapp tweet # 글 관리 (글 쓰기, 삭제, 수정, 댓글) 담당

 

settings.py:

settings.py

settings.py는 Django가 서버를 실행하면서 알아야 할 정보들을 적는다

INSTALLED_APPS에 우리가 만든 앱을 추가해 줌

 

데이터베이스 연결하기

 

장고를 한번이라도 실행했다면 장고는 settings.py의

DATABASES 정보를 가지고 데이터베이스와 자동으로 연동한다

 

좌 : 왼쪽 프로젝트 탐색기 / 우 : settings.py

 

Pycharm

우측 [Database] - [+] - [Data Source from Path]

 

[db.sqlite3] - [SQLite] - OK

 

[Test Connection] 완료!

 


 

ORM(Object Relational Mapping)

 

데이터베이스를 하나의 객체라고 하여 데이터들을 하나의 클래스로 본다

데이터베이스 언어인 SQL언어가 아닌, 파이썬으로 쉽게 다루게 해준다

여러 속성을 가진 클래스데이터베이스로 적용하는 것.

 

User model 만들기

 

이름, 비밀번호, 상태메시지, 생성일 등 필요

 

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


# Create your models here.
class UserModel(models.Model):
    # DB 테이블의 이름을 지정해 주는 정보, DB에 정보를 넣어 주는 역할
    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)

 

Django 모델 필드의 종류

 

  • 문자열 : CharField, TextField
  • 날짜/시간: DateTimeField, DateField, TimeField
  • 숫자 : IntegerField, FloatField
  • 다른 테이블과 연관을 지어 줄 때 : ForeignKey

 


 

만든 모델 데이터베이스에 넣기

 

makemigrations

 

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

 

python manage.py makemigrations

 

migrate

 

변경된 데이터베이스를 적용시켜주는 명령어

 

python manage.py migrate

 

 

장고가 미리 만들어놓은 데이터베이스의 정보와 함께

user.0001은 방금 만든 유저

 

 

Database에도 들어가 있는 것 확인 완료!

 


 

admin

 

장고 서버를 실행시켜주고, /admin으로 접속하면 아래와 같은 관리자 페이지가 나온다

 

 

다시 서버를 실행을 중지시키고 터미널 창에 입력

 

python manage.py createsuperuser

 

 

패스워드는 입력하는 것이 안 보이는 게 정상

 

user/admin.py:

from django.contrib import admin # 장고에서 admin 툴을 사용하겠다
from .models import UserModel # 우리 위치와 동일하게 있는
                            # models라는 파이썬 파일에서 UserModel을 가져오겠다

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

 

관리자 페이지 / ADD USER MODEL

created_at, updated_at은 장고에서 자동으로 넣어준다

 

tweet/models.py:

from django.db import models
from user.models import UserModel # user 앱에 있는 모델 중 UserModel을 가져오겠다

class TweetModel(models.Model):
    class Meta:
        db_table = "tweet"

    # ForeingKey : 다른 데이터베이스에서 내용을 가져오겠다
    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)

 

python manage.py makemigrations # tweet 모델 만들었어
python manage.py migrate # 데이터베이스에 넣어줘

 

tweet/admin.py:

from django.contrib import admin
from .models import TweetModel

admin.site.register(TweetModel)

 


 

화면 띄우기

 

{% %} : 장고 템플릿 문법

 

중복되는 html을 작성하지 않도록 이어서 작성할 수 있게 도와주고,

html에 파이썬의 기능들을 추가할 수 있게 도와준다

 

템플릿 | Django 문서 | Django (djangoproject.com)

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

url-view-template 이어주기

 

 

urls.py:

from django.contrib import admin
from django.urls import path, include

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

 

user/views.py:

from django.shortcuts import render

def sign_up_view(request):
    return render(request, 'user/signup.html')

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

 

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

 

html 파일들을 view와 연결시켜 view가 url과 연결되어 접속 화면이 보여지게 된 것

 

sign-in / sing-up

 


 

회원가입 기능 만들기

  • GET : 값을 읽어 올 때
  • POST : 값을 주거나 수정, 삭제를 요청할 때

 

user/views.py:

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: # 회원가입 시, 이미 있는 사용자인지 확인하는 코드 추가
            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') # 회원가입이 완료되었을 때만 실행

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

 

templates/user/signup.html:

# 화면의 데이터를 서버로 전송할 때 사용하는 <form>태그
# 어떤 방식으로 : POST
# 어떤 url로 전달될 건지 : action
# 어디 url로 전달할 건지 : /sign-up/ ('/' 필수)

<form class="form-area" method="POST" action="/sign-up/">
	{% csrf_token %} # Django에서 POST할 때 보안을 위해 사용
    
    <div>
    	<button>회원가입</button>
    </div>

# button이 form 안에 있으면 해당 form을 실행시켜 주는 역할을 한다

 


 

로그인 기능 만들기

 

  • 세션 : 누가 요청하는지 확인할 수 있도록 도와주는 기능. 사용자 정보를 저장하는 공간!

 

user/views.py:

from django.shortcuts import render, redirect
from .models import UserModel
from django.http import HttpResponse

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 = 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')

def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None) # request.POST에 담겨있는 데이터에서 가져오겠다
        password = request.POST.get('password', None)

        me = UserModel.objects.get(username=username) # UserModel 클래스에서 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')

 

templates/user/signup.html:

# action과 method의 자리는 바껴도 상관 없음
<form class="form-area" action="/sign-in/" method="post"> 
    {% csrf_token %}