django를 활용한 동적 웹사이트 제작 및 AWS 배포

신민창·2021년 2월 10일
0

프로젝트

목록 보기
2/5

django를 활용하여 동적 음원 웹 사이트를 제작하였다.

기능적 요구사항으로 회원가입,로그인, 로그아웃 기능
음원 재생 기능, 음원 리스트, 앨범 리스트 조회 기능, 플레이리스트 음원 추가 및 삭제 기능이 있고
이를 구현하는 것을 목표로 잡았다.

회원 회원가입, 로그인, 로그아웃 기능

user/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.

class User(AbstractUser):
    pass

user/view.py

from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import redirect
from .models import User

# Create your views here.

def login_view(request):
    if request.method == "POST":
        username = request.POST["username"]
        password = request.POST["password"]
        user = authenticate(username= username, password = password)
        if user is not None:
            login(request, user)
            return redirect("index")
            #print("로그인 성공")
            # request.session["loginuser"] = user.user_name 
            #return HttpResponseRedirect('blog/templates/index.html')

        else:
            print("로그인 실패")
    # return redirect('index')
    return render(request, "users/login.html")

def logout_view(request):
    logout(request)
    return redirect("index")


def signup_view(request):
    if request.method == "POST":
        print(request.POST)
        username = request.POST["username"]
        password = request.POST["password"]
        name = request.POST["name"]
        email = request.POST["email"]

        user = User.objects.create_user(username, email, password)
        user.name = name
        user.save()

        return redirect("user:login")

    return render(request, "users/signup.html")

users/templates/users/login.html

<!DOCTYPE HTML>
{% load static %}
<html lang="en">
<head>
	<title>Login V10</title>
	<meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
<!--===============================================================================================-->	
	<link rel="icon" type="image/png" href="{% static 'images/icons/favicon.ico' %}"/>
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'fonts/font-awesome-4.7.0/css/font-awesome.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'fonts/Linearicons-Free-v1.0.0/icon-font.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/animate/animate.css' %}">
<!--===============================================================================================-->	
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/css-hamburgers/hamburgers.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/animsition/css/animsition.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/select2/select2.min.css' %}">
<!--===============================================================================================-->	
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/daterangepicker/daterangepicker.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'css/util.css' %}">
	<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<!--===============================================================================================-->
</head>
<body>
    <div class="limiter">
        <div class="container-login100">
            <div class="wrap-login100 p-t-50 p-b-90">
                
                    <span class="login100-form-title p-b-51">
						Login
					</span>
            {% if user.is_authenticated %}
            로그인 성공
            {{ user.username}}님 환영합니다.
            <div class="container-login100-form-btn m-t-17">
                <a href="{% url 'index' %}">
                <button class="login100-form-btn">
                    홈페이지
                </button>
                </a>
            </div>
            <div class="container-login100-form-btn m-t-17">
            <a href ="{% url 'user:logout' %}">
                <button class="login100-form-btn">
                    Logout
                </button>
            </a>
            </div>
            {% else %}
    
            <form action="" method="POST">
            {% csrf_token %}
                <div class="wrap-input100 validate-input m-b-16" data-validate = "Username is required">
                아이디<input name="username" type="text">
                </div>
                <div class="wrap-input100 validate-input m-b-16" data-validate = "Password is required">
                비밀번호<input name="password" type="password">
                </div>
                <div class="container-login100-form-btn m-t-17">
                    <a href="{% url 'index' %}">
                    <button class="login100-form-btn">
                        Login
                    </button>
                </a>
                </div>
            </form>
            <div class="container-login100-form-btn m-t-17">
                <a href = "{% url 'user:signup' %}">
                    <button class="login100-form-btn">
                        Signup
                    </button>
                </a>
            </div>
            {% endif %} 
        
        </div>
    </div>
</div>
<!-- jQuery -->
<!--===============================================================================================-->
<script src="{% static 'vendor/jquery/jquery-3.2.1.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/animsition/js/animsition.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/bootstrap/js/popper.js' %}"></script>
	<script src="{% static 'vendor/bootstrap/js/bootstrap.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/select2/select2.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/daterangepicker/moment.min.js' %}"></script>
	<script src="{% static 'vendor/daterangepicker/daterangepicker.js ' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/countdowntime/countdowntime.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'js/main1.js' %}"></script>

</body>

</html>

users/templates/users/signup.html


<!DOCTYPE HTML>
{% load static %}
<html lang="en">
<head>
	<title>Login V10</title>
	<meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
<!--===============================================================================================-->	
	<link rel="icon" type="image/png" href="{% static 'images/icons/favicon.ico' %}"/>
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'fonts/font-awesome-4.7.0/css/font-awesome.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'fonts/Linearicons-Free-v1.0.0/icon-font.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/animate/animate.css' %}">
<!--===============================================================================================-->	
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/css-hamburgers/hamburgers.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/animsition/css/animsition.min.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/select2/select2.min.css' %}">
<!--===============================================================================================-->	
	<link rel="stylesheet" type="text/css" href="{% static 'vendor/daterangepicker/daterangepicker.css' %}">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="{% static 'css/util.css' %}">
	<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<!--===============================================================================================-->
</head>
<body>
    <div class="limiter">
        <div class="container-login100">
            <div class="wrap-login100 p-t-50 p-b-90">
                
                    <span class="login100-form-title p-b-51">
						SIGNUP
					</span>
            <form action="" method="POST">
            {% csrf_token %}
                <div class="wrap-input100 validate-input m-b-16" placeholder="Username">
                    ID<input name="username" type="text" >
                </div>
                <div class="wrap-input100 validate-input m-b-16" placeholder="Password">
                    비밀번호<input name="password" type="password">
                </div>
                <div class="wrap-input100 validate-input m-b-16" placeholder="Name">
                    이름<input name="name" type="text">
                </div>
                <div class="wrap-input100 validate-input m-b-16" placeholder="Email">
                    이메일<input name="email" type="text">
                </div>
                <div class="container-login100-form-btn m-t-17">
                    <button class="login100-form-btn">
                        SIGNUP
                    </button>
                </div>
            </form>
        
        </div>
    </div>
</div>
<!-- jQuery -->
<!--===============================================================================================-->
<script src="{% static 'vendor/jquery/jquery-3.2.1.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/animsition/js/animsition.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/bootstrap/js/popper.js' %}"></script>
	<script src="{% static 'vendor/bootstrap/js/bootstrap.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/select2/select2.min.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/daterangepicker/moment.min.js' %}"></script>
	<script src="{% static 'vendor/daterangepicker/daterangepicker.js ' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'vendor/countdowntime/countdowntime.js' %}"></script>
<!--===============================================================================================-->
	<script src="{% static 'js/main1.js' %}"></script>

</body>

</html>

이렇게 회원가입/ 로그인/ 로그아웃 기능을 구현하였다.

다음으로 음원 사이트 측 기능 구현 코드이다.

blog/models.py

from django.db import models
from django.urls import reverse
from django.db.models.deletion import CASCADE, SET_DEFAULT, SET_NULL
from users.models import User


class Category(models.Model):
    name = models.CharField(max_length=50, help_text="음악 장르를 입력하세요")

    def __str__(self):
        return self.name


class Music(models.Model):
    music_no = models.AutoField(primary_key=True)
    music_name = models.CharField(max_length=20)
    music_artist = models.ForeignKey("Artist", related_name="artist", on_delete=models.CASCADE)
    music_composer = models.CharField(max_length = 15)
    music_lyricsist = models.CharField(max_length = 15)
    music_lyrics = models.TextField()
    music_file = models.FileField(default='')

    def __str__(self):
        return self.music_name

class Artist(models.Model):
    artist_no = models.AutoField(primary_key=True)
    artist_name = models.CharField(max_length=15)
    artist_category = models.ManyToManyField(Category, help_text="음악 장르를 설정하세요")

    def __str__(self):
        return self.artist_name

class Album(models.Model):
    album_no = models.AutoField(primary_key=True)
    album_name = models.CharField(max_length=15, default='')
    album_artist_no = models.ForeignKey("Artist", related_name="album_artist", on_delete=models.CASCADE, default='')
    album_image = models.ImageField(blank = True, null=True)
    album_decribe = models.TextField(null=True)
    album_music = models.ManyToManyField(Music)

    def __str__(self):
        return self.album_name

class PlayList(models.Model):
    list_no = models.AutoField(primary_key=True)
    user_no = models.ForeignKey("users.User", related_name = "playlist_user_no", on_delete=models.CASCADE, null=True)
    music_no = models.ForeignKey("Music", related_name = "playlist_music_no", on_delete=models.CASCADE, null=True)
    

    def get_music_no(self):
        return self.music_no

    def __str__(self):
        return f'{self.user_no} playlist'

blog/view.py

from django.shortcuts import render, redirect
from blog.models import Category, Music, Artist, Album, PlayList
from users.models import User
# Create your views here.
def index(request):
    context = {

    }
    return render(request, 'index.html', context=context)

def single(request):
    album_list = Album.objects.all()
    context = {"album_list": album_list }
    return render(request, 'single.html', context= context)

def chart(request) : #curr_page : 현재 페이지
    music_list = Music.objects.all()
    print(music_list)
    context = {"music_list" : music_list}
    return render(request, "chart.html", context )

def playlist(request):
    user_playlist = PlayList.objects.filter(user_no=request.user)
    musics = []
    for i in user_playlist:
        music = i.get_music_no()
        musics.append(Music.objects.filter(music_name=music))

    return render(request, 'playlist.html',{"play_list" : musics})

def list_add(request, music_no):
    user_no = request.user
    list_music_no = Music.objects.get(pk = music_no)
    my_list = PlayList(user_no = user_no, music_no=list_music_no)
    my_list.save()

    return redirect("/blog/playlist")

def list_delete(request, music_no):
    user_no = request.user
    list_music_no = Music.objects.get(pk = music_no)
    my_list = PlayList.objects.filter(user_no = user_no, music_no = list_music_no)
    my_list.delete()
    return redirect("/blog/playlist")

def albumdetail(request, list_id):
    
    albumdetail = Album.objects.get(pk = list_id)
    context = {"albumdetail": albumdetail}

    return render(request, "albumdetail.html", context)


def musicdetail(request, list_id):

    musicdetail = Music.objects.get(pk = list_id)
    context = {"musicdetail" : albumdetail}

    return render(request, "musicdetail.html", context)

이렇게 클래스를 통해서 만든 테이블과 views 기능을 토대로 음원 사이트를 제작하였다.
제작한 다음의 사이트 모습은 다음과 같다.


메인 페이지


뮤직 페이지


앨범 페이지


플레이 리스트 페이지

모든 코드는
https://github.com/tlsalsckd13/django
해당 위치에 업로드 해 놓았다.

AWS에 배포

VPC 생성
서브넷 생성
라우팅 테이블 생성 및 설정
인터넷 게이트웨이 생성
보안 그룹 생성

AWS RDS/RDS 서브넷 생성
aws-mysql-django 연결

EC2 인스턴스 UBUNTU로 생성 후 접속

보안 그룹 - 인바운드 규칙 - 사용자 지정 TCP / 위치 무관 추가

  1. Git과 django 설치
    sudo apt-get update
    sudo apt-get install git
    sudo apt-get install python3-pip
    sudo pip3 install django
    python3 -m pip install Pillow

  2. Git에서 코드 불러와 실행
    git clone <Git 주소>
    manage.py가 있는 디렉토리로 이동
    python3 manage.py runserver 0.0.0.0:8000

  3. 브라우저에 접속
    브라우저에서 EC2 - Running instances - Public DNS뒤에 :8000붙인 주소로 접속하면 동작하는 것을 볼 수 있다.

GCP도 거의 비슷한 방법으로 가능하다.

시스템 아키텍처

Public subnet을 한개만 쓴 이유 : 자원 사용을 최소화하기 위해서

차후 개선 사항

0개의 댓글