▶️ Django 

Django Project 이름은 core이에요.
Bootstrap으로 프런트 작업을 할 거기 때문에 Django로 해주었어요.
내비게이션 바 : 🔗 공식 문서

초반 설정

더보기

1. Github에서 팀 Repositoris을 로컬에 clone 하기

$ git clone <팀 repositoris url>

 

2. VSCode에서 branch 생성하기

# branch 생성하기
$ git branch <branch name>

 

3. 생성한 branch로 이동하기

# branch로 이동하기
$ git switch <branch name>

 

4. 가상환경 생성 및 실행하기

# 가상환경 생성
$ python -m venv <가상환경 이름>

# 가상환경 실행(macOS)
$ source <가상환경 이름>/bin/activate

 

5. requirements.txt 설치하기

# install requirements.txt
$ pip install -r requirements.txt

Django 시작!

⚙️ 회원가입

⚙️ core/urls.py

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

urlpatterns = [
    ...
    path('account/', include('accounts.urls')),
]

⚙️ accounts/models.py

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


class User(AbstractUser):
    message = models.TextField()
$ python manage.py makemigrations
$ python manage.py migrate

⚙️ accounts/urls.py

 

API 명세서에 적어두었던 URL을 토대로 설정해 줬어요.

from django.conf import urls
from django.urls import path
from . import views


urlpatterns = [
    path("register/", views.Register, name="register" ) # 회원 가입
]

⚙️ accounts/views.py

from django.shortcuts import render, redirect
from .forms import CustomUserCreationForm
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout

# 회원가입
def Register(request):
    if request.method == "POST":
        form = CustomUserCreationForm(request.POST)   # 바인딩 form
        if form.is_valid():
            user = form.save()
            auth_login(request, user) # 로그인 하기
            return redirect("main")
    else:
        form = CustomUserCreationForm()
    context = {'form': form}
    return render(request, "accounts/register.html", context)

⚙️ accounts/forms.py

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import get_user_model
from django.urls import reverse

class CustomUserCreationForm(UserCreationForm):
    
    class Meta:
        model = get_user_model()
        fields = UserCreationForm.Meta.fields + ()

⚙️ template/accounts/register.html

더보기
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Form</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <!-- As a link -->
    <nav class="navbar navbar-light" style="background-color: #FFFFFF;">
        <div class="container-fluid">
            <a class="navbar-brand" href="{% url "users:main" %}">BW</a>
            <hr>
        </div>
    </nav>
    <style>
        body {
            font-family: sans-serif;
            background-color:rgb(255, 255, 255); /* Light gray background */
            display: flex;
            flex-direction: column;
            min-height: 100vh; /* Ensure full height */
        }

        /* Main Container */
        .main-container {
            flex: 1; /* Allow the main container to take up remaining space */
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* Login Form Container */
        .login-container {
            width: 400px;
            padding: 20px;
            background-color: #fff;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        .form-control {
            margin-bottom: 15px;
        }

        .btn-primary {
            background-color: #343a40;
            border-color: #343a40;
            width: 100%;
        }

        .btn-primary:hover {
            background-color: #23272b;
            border-color: #23272b;
        }

        /* Footer */
        .footer {
            text-align: center;
            padding: 20px;
            color: #6c757d;
        }

        /* Rounded corners for the whole page */
        html, body {
            border-radius: 10px; /* Round the corners */
            overflow: hidden; /* Hide any overflow */
        }
    </style>
</head>
<body>
    <h1><center>Register</center></h1>
        <br><br>
    <div class="main-container">
        <div class="login-container">
            <form>
                <div class="form-group">
                    <label for="name">Name</label>
                    <input type="text" class="form-control" id="name" placeholder="Enter your name">
                </div>
                <div class="form-group">
                    <label for="surname">Surname</label>
                    <input type="text" class="form-control" id="surname" placeholder="Enter your surname">
                </div>
                <div class="form-group">
                    <label for="password">Password</label>
                    <input type="password" class="form-control" id="password" placeholder="Enter your password">
                </div>
                <div class="form-group">
                    <label for="email">Email</label>
                    <input type="text" class="form-control" id="email" placeholder="Enter your email">
                </div>
                <div class="form-group">
                    <label for="message">Message</label>
                    <input type="text" class="form-control" id="message" placeholder="Enter your message">
                </div>
                <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </div>

    <div class="footer">
        <hr>
        © 2025
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

 

서버에 들어가면 이렇게 나와요.

 

Figma에 써놨던 것과 최대한 비슷한 디자인으로 구성했어요.


⚙️ 로그인

⚙️ user/urls.py

from django.urls import path, include
from .views import login

urlpatterns = [
    path('login/', login, name='login'),
]

⚙️ user/views.py

from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout

# 로그인
def login(request):
    if request.method == "POST":
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            # Log the user in
            auth_login(request, form.get_user())   # 로그인 하기
            next_url = request.GET.get("next") or "main"
            return redirect(next_url)
    
    else:    
        form = AuthenticationForm()
    context = {'form': form}
    return render(request, 'login.html', context)

⚙️ user/login.html

더보기
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Form</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    
    <!-- As a link -->
    <nav class="navbar navbar-light" style="background-color: #FFFFFF;">
        <div class="container-fluid">
            <a class="navbar-brand" href="{% url "users:main" %}">BW</a>
        </div>
    </nav>
    <style>
        body {
            font-family: sans-serif;
            background-color:rgb(255, 255, 255); /* Light gray background */
            display: flex;
            flex-direction: column;
            min-height: 100vh; /* Ensure full height */
        }

        /* Main Container */
        .main-container {
            flex: 1; /* Allow the main container to take up remaining space */
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* Login Form Container */
        .login-container {
            width: 400px;
            padding: 20px;
            background-color: #fff;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        .form-control {
            margin-bottom: 15px;
        }

        .btn-primary {
            background-color: #343a40;
            border-color: #343a40;
            width: 100%;
        }

        .btn-primary:hover {
            background-color: #23272b;
            border-color: #23272b;
        }

        /* Footer */
        .footer {
            text-align: center;
            padding: 20px;
            color: #6c757d;
        }

        /* Rounded corners for the whole page */
        html, body {
            border-radius: 10px; /* Round the corners */
            overflow: hidden; /* Hide any overflow */
        }
    </style>
</head>
<body>
    <div class="main-container">
        <div class="login-container">
            <h2 class="text-center mb-4">Login</h2>
            <form>
                <div class="form-group">
                    <label for="id">ID</label>
                    <input type="text" class="form-control" id="id" placeholder="Enter your ID">
                </div>
                <div class="form-group">
                    <label for="password">Password</label>
                    <input type="password" class="form-control" id="password" placeholder="Enter your password">
                </div>
                <button type="submit" class="btn btn-primary">Submit</button>
            </form>
            <div class="text-center mt-3">
                <a href="{% url "accounts:register" %}">Register</a> | <a href="#">Forgot your password?</a>
            </div>
        </div>
    </div>

    <div class="footer">
        <hr>
        © 2025
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>


⚙️ 로그아웃

⚙️ users/urls.py

urlpatterns = [
    ...
    path('logout/', logout, name='logout'), # 로그아웃
]

⚙️ users/views.py

# 로그아웃
@login_required
def logout(request):
    auth_logout(request)    # 로그아웃 하기
    return redirect('main')

⚙️ users/template/main.html

더보기
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Gallery</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <!-- As a link  Header-->
    <nav class="navbar navbar-light bg-transparent border-bottom"> <!--배경색 투명, 선으로만 보이게끔-->
        <div class="container-fluid">
            <a class="navbar-brand text-dark" href="{% url "users:main" %}"><strong>BW</strong></a>
            <div class="d-flex">
                <a class="btn btn-dark btn-sm me-2" href="{% url "users:login" %}">Log In</a>
                <a class="btn btn-dark btn-sm" href="{% url "accounts:register" %}">Register</a>
            </div>
        </div>
    </nav>

    <style>
        body {
            font-family: sans-serif;
            background-color:rgb(255, 255, 255);
            min-height: 100vh; /* 최소 높이를 100vh로 설정하여 화면 전체를 채우도록 함 */

        }
        .wrapper {
            display: flex;
            flex-direction: column; /* 내용을 세로로 정렬 */
            min-height: 100vh; /* 최소 높이를 100vh로 설정하여 body와 동일하게 함 */
        }

        .container {
            margin-top: 20px;
        }
        .card {
            margin-bottom: 20px;
            padding: 10px;
        }
        .card-img-top {
            background-color: #f0f0f0; /* Placeholder gray color */
            height: 200px;
            display: flex;
            justify-content: center;
            align-items: center;
            margin-bottom: 10px;
        }
        .card-title {
            font-size: 16px;
            text-align: center;
        }
        .col-md-9 {
            margin: 0 auto; /* 좌우 마진을 auto로 설정 */
            float: none;    /* float 속성 제거 */
        }
        .btn-custom {
            background-color: white;
            color: black;
            border: 1px solid #ced4da;
            border-radius: 5px;
            margin-bottom: 5px;
            padding: 8px 12px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .btn-custom:hover {
            background-color: #e9ecef; /* Light gray on hover */
        }

        .btn-custom i {
            margin-left: 5px; /* Space between text and icon */
        }
        .placeholder-image {
            width: 100%;
            height: 200px; /* Adjust as needed */
            background-color: #f0f0f0;
            border: 1px solid #ddd;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #aaa;
            margin-bottom: 10px; /* Added spacing between images */
        }

        .placeholder-image svg {
            width: 50%; /* Adjust size as needed */
            height: 50%;
        }

    </style>
</head>
<body>
    <div class="wrapper">
        <nav class="navbar navbar-light bg-transparent">
            </nav>
        <div class="container-fluid">
            <div class="row">
                <!--Left button-->
                <div class="col-md-3">
                    <button class="btn-custom w-100">Created from text <i class="fas fa-file"></i></button>
                    <button class="btn-custom w-100">Created from image <i class="fas fa-image"></i></button>
                </div>
        
                <!-- Image Gallery (Right) -->
                <div class="col-md-9">
                    <div class="row">
                        <div class="col-md-4">
                            <div class="card">
                                <div class="card-img-top">
                                    <i class="fas fa-image fa-5x" style="color: lightgray;"></i>
                                </div>
                                <div class="card-body">
                                    <p class="card-title">Text</p>
                                </div>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="card">
                                <div class="card-img-top">
                                     <i class="fas fa-image fa-5x" style="color: lightgray;"></i>
                                </div>
                                <div class="card-body">
                                    <p class="card-title">Text</p>
                                </div>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="card">
                                <div class="card-img-top">
                                     <i class="fas fa-image fa-5x" style="color: lightgray;"></i>
                                </div>
                                <div class="card-body">
                                    <p class="card-title">Text</p>
                                </div>
                            </div>
                        </div>
                    </div>
        
                     <div class="row">
                        <div class="col-md-4">
                            <div class="card">
                                <div class="card-img-top">
                                    <i class="fas fa-image fa-5x" style="color: lightgray;"></i>
                                </div>
                                <div class="card-body">
                                    <p class="card-title">Text</p>
                                </div>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="card">
                                <div class="card-img-top">
                                     <i class="fas fa-image fa-5x" style="color: lightgray;"></i>
                                </div>
                                <div class="card-body">
                                    <p class="card-title">Text</p>
                                </div>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="card">
                                <div class="card-img-top">
                                     <i class="fas fa-image fa-5x" style="color: lightgray;"></i>
                                </div>
                                <div class="card-body">
                                    <p class="card-title">Text</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

    <!--Footer-->
    <footer class="py-0 bg-transparent border-top fixed-bottom"> <!--배경은 투명, 선으로만-->
        <div class="container">
            <p class="m-3 text-center text-color: rgb(195, 193, 193)">@ 2025</p>
        </div>
    </footer>
</body>
</html>

카드 레이아웃 공식 문서 🔗 https://getbootstrap.kr/docs/5.3/components/card/

footer 설정할 때 참고한 블로그 🔗 https://blog.naver.com/mininuke7303/221990134184


배경색 관련 공식 문서 🔗 https://getbootstrap.kr/docs/5.0/utilities/background/

테두리 관련 공식 문서 🔗 https://getbootstrap.kr/docs/5.0/utilities/borders/

✅ header 배경색, 테두리 설정하기

<nav class="navbar navbar-light bg-transparent border-bottom"> <!--배경색 투명, 선으로만 보이게끔-->

footer 배경색, 테두리 설정하기

<footer class="py-0 bg-transparent border-top fixed-bottom"> <!--배경은 투명, 선으로만-->

 

공통적으로 bg-transparent가 있죠?

이게 배경색을 투명으로 바꾸는 설정이에요.

그리고

border가 테두리를 의미해요

header에는 bottom에만 테두리 선을 설정해 주었고,

footer에는 top에만 테두리 선을 설정해 주었어요.


마무리

하면서 느꼈지만, header랑 footer를 그냥 따로 빼서 html로 관리해 줘야겠어요.

내일 설정해야겠어요 히히,, 눈 빠지는 줄 알았어요.

 

🐾Recent posts