[Django] clone instagram #6

์ •๋ณด๊ตฌ๋‹ˆยท2021๋…„ 12์›” 6์ผ
0

Django

๋ชฉ๋ก ๋ณด๊ธฐ
14/15
post-thumbnail

๋กœ๊ทธ์ธ์ด๋‚˜ ํšŒ์›๊ฐ€์ž…์„ ์œ„ํ•œ ์œ ์ € ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค.

์žฅ๊ณ ์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ์œ ์ € ๋ชจ๋ธ(auth _user)์ด ์žˆ๋‹ค

๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณต๋˜๋Š” auth_user๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ํ•„์ˆ˜ ๊ธฐ๋ณธ ํ•จ์ˆ˜์ธ passwordcheck๋‚˜ ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ์œ ์ € ๋ชจ๋ธ์— ์›ํ•˜๋Š” field๊ฐ€ ์—†์„ ๊ฒฝ์šฐ, ์œ ์ € ๋ชจ๋ธ์„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์ƒˆ๋กœ์šด ์œ ์ € ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด ์ค„ ๋•Œ๋Š” ๊ธฐ์กด์˜ auth_user๋ฅผ ๊ฐ€์ ธ๊ฐ€๋ฉด์„œ ์ปค์Šคํ…€ํ•˜์—ฌ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ•๊ณผ, auth_user๋Š” ๋ฌด์‹œํ•œ ์ฑ„ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

์•„์˜ˆ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด ์ค„ ๊ฒฝ์šฐ์—๋Š” ๊ธฐ์กด ์œ ์ €๋ชจ๋ธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•„์ˆ˜ ๊ธฐ๋ณธ ํ•จ์ˆ˜๋„ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด ์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—
๊ธฐ์กด ์œ ์ €๋ชจ๋ธ์„ ์‚ด๋ฆฌ๋ฉด์„œ ์ปค์Šคํ…€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค


์ด๋•Œ ์žฅ๊ณ ์—์„œ defalt๋กœ ์‚ฌ์šฉํ•˜๋Š” ์œ ์ €๋ชจ๋ธ์€ 1๊ฐœ์—ฌ์•ผ ํ•œ๋‹ค.
์ง€๊ธˆ์€ ์ด๋ฏธ ๊ธฐ๋ณธ ์œ ์ €๋ชจ๋ธ์ด DB์— ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋œ ์ƒํƒœ์ด๋ฏ€๋กœ, ๊ธฐ๋ณธ ์œ ์ €๋ชจ๋ธ์— ๋Œ€ํ•œ DB๋ฅผ ์ง€์›Œ์ฃผ๊ณ  ์ปค์Šคํ…€ ์œ ์ €๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์žฅ๊ณ ๋ฅผ ์ด์šฉํ•ด ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๋•Œ ๋จผ์ € ์‚ฌ์šฉ์ž ๋ชจ๋ธ์„ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•˜๊ณ  ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค



์ปค์Šคํ…€ ์œ ์ €๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ


์›๋ž˜ ์žˆ๋˜ ์žฅ๊ณ ์˜ ๊ธฐ๋ณธ ์œ ์ €๋ชจ๋ธ์„ ์ง€์›Œ์ค€ ๋’ค ์ปค์Šคํ…€ ์œ ์ € ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด์ค€๋‹ค

user/models.py

from django.contrib.auth.base_user import AbstractBaseUser


class User(AbstractBaseUser):
    """
        ์œ ์ € ํ”„๋กœํ•„ ์‚ฌ์ง„
        ์œ ์ € ๋‹‰๋„ค์ž„        -> ํ™”๋ฉด์— ํ‘œ๊ธฐ๋˜๋Š” ์ด๋ฆ„
        ์œ ์ € ์ด๋ฆ„          -> ์‹ค์ œ ์‚ฌ์šฉ์ž ์ด๋ฆ„
        ์œ ์ € ์ด๋ฉ”์ผ ์ฃผ์†Œ   -> ํšŒ์›๊ฐ€์ž…ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์•„์ด๋””
        ์œ ์ € ๋น„๋ฐ€๋ฒˆํ˜ธ      -> ๊ธฐ๋ณธ๊ฐ’ ์“ฐ์ž
    """

    profile = models.TextField() 
    nickname = models.CharField(max_length=24, unique=Ture)
    name = models.CharField(max_length=24)
    email = models.EmailField(unique=Ture)

    USERNAME_FIELD = 'nickname'

    class Meta:
        db_table = "User"
  • class Meta: db_table = "User"
    db ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„์„ ๊ธฐ์กด๋ฐฉ์‹์ธ ์•ฑ์ด๋ฆ„_ํด๋ž˜์Šค์ด๋ฆ„(user_User)์ด ์•„๋‹Œ ์›ํ•˜๋Š”๋Œ€๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๋งŒ๋“ค์–ด์ค€ ์ปค์Šคํ…€ ์œ ์ €๋ชจ๋ธ์„ settings ํŒŒ์ผ์— ๋“ฑ๋ก์‹œ์ผœ์ค€๋‹ค

instagram/settins.py

...
AUTH_USER_MODEL = 'user.User'  # ์ปค์Šคํ…€ ์œ ์ € ๋ชจ๋ธ ๋“ฑ๋ก

DB๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ ์œ„ํ•ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•ด์ค€๋‹ค.

(venv) python manage.py makemigrations
(venv) python manage.py migrate


๊ทธ๋Ÿผ User๋ผ๋Š” ์ด๋ฆ„์˜ ํ…Œ์ด๋ธ”์ด ์ƒ๊ธด ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.



์•ฑ๋งˆ๋‹ค urls ๋ถ„๋ฆฌํ•˜๊ธฐ


urls๋„ ์•ฑ๋งˆ๋‹ค ๋‚˜๋ˆ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

ํ˜„์žฌ๋Š” instagram/urls.py ํŒŒ์ผ์—์„œ ๋ชจ๋“  url์„ ์žˆ์ง€๋งŒ, ์•ฑ๋งˆ๋‹ค ๋ถ„๋ฆฌ๋ฅผ ์‹œ์ผœ๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

content ํด๋”์— urls.py ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ์ค€ ๋‹ค์Œ
๊ธฐ์กด itagram/urls.pyํŒŒ์ผ๋„ ์ˆ˜์ •ํ•ด์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค.

content/urls.py

from django.urls import path
from .views import UploadFeed 


urlpatterns = [
    path('upload', UploadFeed.as_view())
]

instagram/urls.py

...

urlpatterns = [
    ...
    # path('content/upload', UploadFeed.as_view())
    path('content/', include('content.urls'))
]
...

include๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ์•ฑ์˜ urls.py๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.



ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ


๋จผ์ € ๋ทฐ๋ฅผ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

user/view.py

from django.shortcuts import render
from rest_framework.views import APIView


class Join(APIView):
    def get(self, request):
        return render(request, "user/join.html")

class Login(APIView):
    def get(self, request):
        return render(request, "user/login.html")

urls์„ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค.

user/urls.py

from django.urls import path
from .views import Join, Login

urlpatterns = [
    path('join', Join.as_view()),
    path('login', Login.as_view())
]

์•ฑ urls๋ฅผ ๋ฃจํŠธํด๋”์˜ urls.py์™€ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค.

instagram/urls.py

...

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

ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ html์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

templates/join.html

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

        <title>ํšŒ์›๊ฐ€์ž…</title>
    </head>
    
    <body style="background: rgb(245,245,245)">
        <div style="text-align: center; width: 400px; height: 500px; border: solid 1px gray; margin: 100px auto 20px auto; background: white;">
            <div style="width: 360px; height: 500px; margin: 50px auto 50px auto;">
                <div><img style="width: 160px; margin-bottom:20px;" src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"></div>
                <div style="color: gray; font-weight: bolder; margin-bottom: 60px;"> ์นœ๊ตฌ๋“ค์˜ ์‚ฌ์ง„๊ณผ ๋™์˜์ƒ์„ ๋ณด๋ ค๋ฉด ๊ฐ€์ž…ํ•˜์„ธ์š” </div>

                <div class="form-floating mb-3">
                    <input style="width: 300px; height: 24px; margin: auto;" type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
                    <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="floatingInput">ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ ๋˜๋Š” ์ด๋ฉ”์ผ ์ฃผ์†Œ</label>
                </div>

                <div class="form-floating mb-3">
                    <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="floatingInput" placeholder="name@example.com">
                    <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="floatingInput">์ด๋ฆ„</label>
                </div>

                <div class="form-floating mb-3">
                    <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="floatingInput" placeholder="name@example.com">
                    <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="floatingInput">๋‹‰๋„ค์ž„</label>
                </div>

                <div class="form-floating mb-3">
                    <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="floatingInput" placeholder="name@example.com">
                    <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="floatingInput">๋น„๋ฐ€ ๋ฒˆํ˜ธ</label>
                </div>
                <button style="width: 300px; height: 32px; margin: auto; font-size: 14px; font-weight: bolder; margin-top: 8px;" type="button" class="btn btn-primary">๊ฐ€์ž…</button>
            </div>
        </div>

        <div style="text-align: center; width: 400px; height: 80px; border: solid 1px gray; margin: 20px auto 100px auto; background: white;">
            <div style="margin: 28px auto 28px auto;"> ๊ณ„์ •์ด ์žˆ์œผ์‹ ๊ฐ€์š”? <a href="login">๋กœ๊ทธ์ธ</a></div>
        </div>
        
        <!-- Optional JavaScript; choose one of the two! -->

        <!-- Option 1: Bootstrap Bundle with Popper -->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

        <!-- Option 2: Separate Popper and Bootstrap JS -->
        <!--
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
        -->
    </body>
</html>

templates/login.html

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

        <title>๋กœ๊ทธ์ธ</title>
    </head>

    <body style="background: rgb(245,245,245)">
        <div style="text-align: center; width: 400px; height: 500px; border: solid 1px gray; margin: 100px auto 20px auto; background: white;">
            <div style="width: 360px; height: 500px; margin: 50px auto 50px auto;">
                <div><img style="width: 160px; margin-bottom:20px;" src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"></div>
                <div style="color: gray; font-weight: bolder; margin-bottom: 60px;"> ์นœ๊ตฌ๋“ค์˜ ์‚ฌ์ง„๊ณผ ๋™์˜์ƒ์„ ๋ณด๋ ค๋ฉด ๊ฐ€์ž…ํ•˜์„ธ์š” </div>
                
                <div class="form-floating mb-3">
                    <input style="width: 300px; height: 24px; margin: auto;" type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
                    <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="floatingInput">ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ ๋˜๋Š” ์ด๋ฉ”์ผ ์ฃผ์†Œ</label>
                </div>

                <div class="form-floating mb-3">
                    <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="floatingInput" placeholder="name@example.com">
                    <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="floatingInput">๋น„๋ฐ€ ๋ฒˆํ˜ธ</label>
                </div>
                <button style="width: 300px; height: 32px; margin: auto; font-size: 14px; font-weight: bolder; margin-top: 8px;" type="button" class="btn btn-primary">๋กœ๊ทธ์ธ</button>
            </div>
        </div>

        <div style="text-align: center; width: 400px; height: 80px; border: solid 1px gray; margin: 20px auto 100px auto; background: white;">
            <div style="margin: 28px auto 28px auto;">๊ณ„์ •์ด ์—†์œผ์‹ ๊ฐ€์š”? <a href="join">๊ฐ€์ž…ํ•˜๊ธฐ</a></div>
        </div>
        
        <!-- Optional JavaScript; choose one of the two! -->

        <!-- Option 1: Bootstrap Bundle with Popper -->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

        <!-- Option 2: Separate Popper and Bootstrap JS -->
        <!--
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
        -->
    </body>
</html>



๐Ÿ”Ž ์ฐธ๊ณ 
๊ฐ•์˜

0๊ฐœ์˜ ๋Œ“๊ธ€