Leta Learns

영화 평가 사이트 | 210724 본문

멋쟁이사자처럼 9기/미니 해커톤

영화 평가 사이트 | 210724

leta 2021. 7. 26. 15:41

사회적 거리두기 4단계 때문에 오후 6시 이후로 3명 이상은 만날 수 없기 때문에 이번 미니 해커톤은 7/24, 25 10-18시 까지 이틀 간 진행되었다.

 

 

첫 미니 해커톤 주제 : 영화 평가 사이트 만들기

 

팀원 셋이서 우선 역할을 분담했다. home, detail, user로 역할을 분담했는데 user파트는 금방 끝날 것 같아서 그냥 나와 다른 팀원 한 명이 detail과 user를 같이 하기로 했다. 

 

프로젝트명은 movie로 했는데 작업하면서 보니 movie project라고 프로젝트임을 명시해주는 게 작업 도중에 쉽게 알아보기 좋을 것 같다.

 

 

1. SignUp 기능 구현

먼저 signup 기능을 만들기 위해 account 앱을 만들고 models, views, urls를 수정했다. 폼을 사용하여 작업을 진행할거라 forms.py도 만들었다.

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.
class CustomUser(AbstractUser):
    nickname = models.CharField(max_length=100)
    university = models.CharField(max_length=50)
    location = models.CharField(max_length=200)

 

forms.py 아직 장고에 익숙치 않아 노션을 보고 만들어서 폼도 그대로 사용한 건데 하다보니 굳이 폼으로 안 해도 됐을 것 같다. nickname, university, location 이런 거 굳이 필요 없으니..

from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser

class SignupForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ['username', 'password1', 'password2', 'nickname', 'university', 'location']

 

views.py

from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib import auth
from .forms import SignupForm

# Create your views here.
def signup_view(request):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            user = form.save()
            auth.login(request, user)
            return redirect('home')
        return redirect('account:signup')
    
    else:
        form = SignupForm()
        return render(request, 'signup.html', {'form':form})

 

urls.py

from django.urls import path
from django.urls.resolvers import URLPattern
from . import views

app_name = 'account'
 
urlpatterns = [
    path('signup/', views.signup_view, name='signup'),
]

 

 

model 고친 다음 migrate 해주고 signup.html을 만들었다.

프로젝트 파일에 base.html을 미리 만들어 두고 상속받아서 사용하였다. base.html 상속받는 코드인 {% extends 'base.html' %} 코드는 무조건 1행에 적어야 한다. 꼭!

 

movie/templates/base.html (해커톤 종료 후 기록하는 것이라 이미 NavBar 등등이 모두 완성된 base.html임)

{% load static %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    <title>BLOG</title>
    <style>
      body {
        text-align: center; background-color: white;
        }
    </style>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="container-fluid">
        <a class="navbar-brand" href="{% url 'home' %}">Cinema Review</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Link</a>
            </li>
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                Dropdown
              </a>
              <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
                <li><a class="dropdown-item" href="#">Action</a></li>
                <li><a class="dropdown-item" href="#">Another action</a></li>
                <li><hr class="dropdown-divider"></li>
                <li><a class="dropdown-item" href="#">Something else here</a></li>
              </ul>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
            </li>
            {% if user.is_authenticated %}
                <li class="nav-item">
                    <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">{{request.user}}님
                        안녕하세요!</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'account:logout' %}" tabindex="-1" aria-disabled="true">로그아웃</a>
                </li>

                {% else %}

                <li class="nav-item">
                    <a class="nav-link" href="{% url 'account:login' %}" tabindex="-1" aria-disabled="true">로그인</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'account:signup' %}" tabindex="-1" aria-disabled="true">회원가입</a>
                </li>
                {% endif %}
          </ul>
          <form class="d-flex" action="{% url 'home' %}">
            <input class="form-control me-2" type="text" placeholder="Search" aria-label="Search" name='query'>
            <button class="btn btn-outline-success" type="submit">Search</button>
          </form>
        </div>
      </div>
    </nav>

    <div class = "container">
        {% block content %}
        {% endblock %}
    </div>
  </body>
  
  
</html>

 

account/templates/signup.html

{% extends 'base.html' %}
{% load static %}

{% block content %}

<head>
  <style>
    .helptext, li {
      display: none;
    }
    button {
      border: 1px solid black;
      border-radius: 5px;
      background: blue;
      color: white;
      font-weight: bold;
    }
    .signup_div { position: relative; top: 220px;}
  </style>
</head>

<div class="signup_div">
<h1>Sign Up</h1> <br>
<form action="{% url 'account:signup' %}" method="POST">
  {% csrf_token %}
  {{form.as_p}}

  <button type="submit">회원가입</button>
</form>
</div>
{% endblock %}

 

 

 

 

 

2. detail 페이지 구현

영화 정보를 띄울 detail 페이지 구현은 blog 앱에서 작업했다. 다른 이름으로 했으면 작업하면서 안 헷갈렸을 것 같은데 이것도 일단 노션대로 진행하다보니 후반부에 가서는 헷갈렸다. 다음부턴 노션 보고 하더라도 프로젝트나 앱 이름은 주제에 맞춰서 바꿔야겠다.

 

먼저 detail에 띄울 모델을 만들고 admin에 모델 추가한 후 views, urls을 수정하였다.

blog/models.py

from django.db import models

# Create your models here.
class Movies(models.Model):
    title_kor= models.CharField(max_length=200)
    title_eng= models.CharField(max_length=200)
    poster_url= models.CharField(max_length=500)
    rating_aud= models.CharField(max_length=200)
    rating_cri= models.CharField(max_length=200)
    rating_net= models.CharField(max_length=200)
    genre= models.CharField(max_length=200)
    showtimes= models.CharField(max_length=200)
    release_date= models.CharField(max_length=200)
    rate= models.CharField(max_length=200)
    summary= models.CharField(max_length=200)

 

blog/admin.py (Staff, Comment는 추후 팀원들이 작업)

from django.contrib import admin
from .models import Movies, Staff, Comment

# Register your models here.
admin.site.register(Movies)
admin.site.register(Staff)
admin.site.register(Comment)

 

blog/views.py (Staff, Comment는 추후에 팀원들 작업물 깃으로 받아올 것)

from django.shortcuts import render, redirect, get_object_or_404
from .models import Movies

def detail(request, id): 
    blog = get_object_or_404(Movies, pk = id) 
    #staffs = Staff.objects.filter(number=id)
    #comments = Comment.objects.filter(movie=id)
    return render(request, 'detail.html', {'blog': blog})

 

blog/urls.py

from django.contrib import admin
from django.urls import path
from blog.views import *

app_name='blog'

urlpatterns = [
    path('admin/', admin.site.urls),
    path('<int:id>', detail, name='detail'),
]

 

detail.html은 css도 이것저것해서 고친 게 너무 많으므로 둘째 날 기록에 아예 완성본 html 코드로 올려야 겠다.

 

 

 


 

 

 

장고 미숙한 건 둘째 치고 깃으로 협업하는 게 가장 난관이었다. 팀원 셋 다 깃을 몰라서 운영진분들께 물어보고 난리도 아니었다.. 깃 쓰는 법 공부하고 사람들이랑 연습 좀 해봐야 될 것 같다.

깃에서 시간만 덜 뺐겼어도 장고도 더 멀쩡한 정신으로 수월하게 할 수 있었을 것 같은데 아쉽다.

 

짧은 시간 내에 내 작업도 하고 팀원들 에러나면 같이 봐주기도 하고, 내 에러도 같이 보고 하니까 재밌었다. 물론.. 이런 말을 하면 그게 재밌었던 사람의 표정이었냐고 질문이 들어올 것 같긴 하다. 그래도 멋사 지원할 때부터 협업해보고 싶어서 들어온 거라서 좀 뿌듯했다. 집에 와서도 팀원들이랑 같이 게더타운 켜서 각자 작업했다. 나는 디테일 페이지 좀 더 수정하고 다음 날 CSS 할 거라서 static 처리만 해주었다.

 

이번 주에 장고 과제도 하고, 과제 끝나자마자 해커톤해서 전보다는 확실히 장고에 많이 익숙해진 것 같다. 다음 미니해커톤 때는 더 잘해야지.. 그러려면 일단 무조건 깃부터 제발.

 

둘째 날에는 팀원들이 깃에 올린 작업물 받아서 staff, comment까지 detail페이지에 띄웠다. 이건 둘째 날 포스팅에서 다시 얘기해야지.



 

 

'멋쟁이사자처럼 9기 > 미니 해커톤' 카테고리의 다른 글

영화 평가 사이트 | 210725  (0) 2021.07.27
Comments