๐Ÿ‘ฆ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„/TIL(Today I Learned)

TIL_220530_Django ๊ธฐ์ดˆ

  • -

Django ์˜ ๊ธฐ๋ณธ user ๋ชจ๋ธ(auth_user) ์‚ฌ์šฉํ•˜๊ธฐ (์ƒ์†)

1) ์ƒ์†ํ•˜๊ธฐ ์œ„ํ•œ AbstractUser ์ž„ํฌํŠธ

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

 

2) UserModel ์˜ ์ƒ์†

- ๊ธฐ๋ณธ ๋ชจ๋ธ์— ์—†๋˜ bio ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€

 

# Create your models here.
class UserModel(AbstractUser):

    class Meta:
        db_table = "my_user" # ์—ฌ๊ธฐ๋Š” ํ…Œ์ด๋ธ” ์ด๋ฆ„์ด์—์š”! ๊ผญ ๊ธฐ์–ต ํ•ด ์ฃผ์„ธ์š”!

    bio = models.TextField(max_length=500, blank=True)

 

3) ํ”„๋กœ์ ํŠธ์•ฑ์˜ settings.py ์— ๊ธฐ๋ณธ ์ธ์ฆ๊ณผ์ • ์ ์šฉ

- Django ์—๊ฒŒ ๊ธฐ๋ณธ ์ธ์ฆ๊ณผ์ •(AUTH_USER_MODEL) ์„ user ์•ฑ์— ์ž‘์„ฑํ•œ UserModel ๋กœ ์‚ฌ์šฉ

# mySpartaSns/settings.py
AUTH_USER_MODEL = 'user.UserModel'

 

4) ์ƒˆ๋กœ์šด ๋ชจ๋ธ ์ ์šฉ ์‹œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ์šฉ์‹œํ‚ค๊ธฐ

- python manage.py makemigrations

- python manage.py migrate

 

 

Django์˜ ์‚ฌ์šฉ์ž ๋ชจ๋ธ์„ ์ ์šฉํ•˜๊ธฐ - ํšŒ์›๊ฐ€์ž… ์ˆ˜์ •ํ•˜๊ธฐ

1) user/views.py ์—์„œ ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ์ˆ˜์ •

- ํšŒ์›๊ฐ€์ž… ์ค‘๋ณต๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด get_user_model ์„ ์ž„ํฌํŠธ

# user/views.py
from django.contrib.auth import get_user_model #์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ํ•จ์ˆ˜

 

2) ํšŒ์›๊ฐ€์ž… ์‚ฌ์šฉ ํ•จ์ˆ˜์— get_user_model ์ ์šฉ

get_user_model().objects.filter(username=username) ์œผ๋กœ username ๋ฐ์ดํ„ฐ ๋Œ€์กฐ

exist_user = get_user_model().objects.filter(username=username)
if exist_user:
    return render(request, 'user/signup.html') # ์‚ฌ์šฉ์ž๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋„์›€
else:
    UserModel.objects.create_user(username=username, password=password, bio=bio)
    return redirect('/sign-in') # ํšŒ์›๊ฐ€์ž…์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™

 

 

Django์˜ ์‚ฌ์šฉ์ž ๋ชจ๋ธ์„ ์ ์šฉํ•˜๊ธฐ - ๋กœ๊ทธ์ธ ์ˆ˜์ •ํ•˜๊ธฐ

1) ์‚ฌ์šฉ์ž ๋ชจ๋ธ ์ ์šฉ์„ ์œ„ํ•œ ๋กœ๊ทธ์ธ ์ˆ˜์ •

- ์‚ฌ์šฉ์ž auth ๊ธฐ๋Šฅ ์ž„ํฌํŠธ

# user/views.py
from django.contrib import auth # ์‚ฌ์šฉ์ž auth ๊ธฐ๋Šฅ

 

2) ๋กœ๊ทธ์ธ์˜ views.py ์ˆ˜์ •

auth.authenticate() ๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ์ฒดํฌ

auth.login(request, me) ๋กœ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ์Šน์ธ

me = auth.authenticate(request, username=username, password=password)  # ์‚ฌ์šฉ์ž ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
if me is not None:  # ์ €์žฅ๋œ ์‚ฌ์šฉ์ž์˜ ํŒจ์Šค์›Œ๋“œ์™€ ์ž…๋ ฅ๋ฐ›์€ ํŒจ์Šค์›Œ๋“œ ๋น„๊ต
    auth.login(request, me)
    return HttpResponse("๋กœ๊ทธ์ธ ์„ฑ๊ณต")
else:
    return redirect('/sign-in')  # ๋กœ๊ทธ์ธ ์‹คํŒจ

 

3) ๋กœ๊ทธ์ธ ์Šน์ธ ํ›„ ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ด๋™ ์—ฐ๊ฒฐ

- tweet/home.html ๋ฉ”์ธ์ด ๋˜๋Š” ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑ

- base.html ์˜ ๊ธฐ๋ฐ˜ {% extends 'base.html' %} ์œผ๋กœ {% block content %} & {% endblock %} ์˜์—ญ ์ƒ์„ฑ

 

4) ์ด๋™ํ•  ๋ฉ”์ธ ํŽ˜์ด์ง€ ์—ฐ๊ฒฐ

- ๊ธ€์“ฐ๊ธฐ ๊ธฐ๋Šฅ์ด ํฌํ•จ๋  ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ tweet ์•ฑ์˜ views.py ๋‚ด์šฉ ์ถ”๊ฐ€

request.user.is_authenticated ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ๋ฐ›์•˜๋Š”์ง€(๋กœ๊ทธ์ธ์ด ๋˜์–ด์žˆ๋Š”์ง€)

# tweet/views.py
from django.shortcuts import render, redirect


# Create your views here.
def home(request):
    user = request.user.is_authenticated  # ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ๋ฐ›์•˜๋Š”์ง€ (๋กœ๊ทธ์ธ์ด ๋˜์–ด์žˆ๋Š”์ง€)
    if user:
        return redirect('/tweet')
    else:
        return redirect('/sign-in')


def tweet(request):
    if request.method == 'GET':
        return render(request, 'tweet/home.html')

 

5) tweet ์•ฑ์˜ urls.py ์ƒ์„ฑ

# tweet/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'), # 127.0.0.1:8000 ๊ณผ views.py ํด๋”์˜ home ํ•จ์ˆ˜ ์—ฐ๊ฒฐ
    path('tweet/', views.tweet, name='tweet') # 127.0.0.1:8000/tweet ๊ณผ views.py ํด๋”์˜ tweet ํ•จ์ˆ˜ ์—ฐ๊ฒฐ
]

 

6) ํ”„๋กœ์ ํŠธ ์•ฑ์˜ urls.py ์—์„œ ์ฃผ์†Œ ๋“ฑ๋ก

# mySpartaSns/urls.py

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

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

 

 

๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ ํ‘œ์‹œ

1) ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ ์„ค์ •

'{{ }}' ์„ ์‚ฌ์šฉํ•ด์„œ ๋…ธ์ถœ ํƒœ๊ทธ ๋ถ€๋ถ„์— ์‚ฌ์šฉ์ž ์ด๋ฆ„ : {{ user.username }} & ์‚ฌ์šฉ์ž ์ •๋ณด : {{ user.bio }} ๋ฅผ ๊ฐ๊ฐ ์ž…๋ ฅ

<div class="col-md-3">
    <div class="card">
        <div class="card-body">
            <h5 class="card-title">{{ user.username }}</h5>
            <p class="card-text"> {{ user.bio }}</p>
        </div>
    </div>
</div>

 

2) ํ™”๋ฉด์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ”์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด์— ๋งž๊ฒŒ ๋ณ€ํ•˜๋Š” ์˜์—ญ์„ ์‚ฌ์šฉ์ž ์ธ์ฆ ์กฐ๊ฑด์— ๋งž๊ฒŒ ์„ค์ •

{% if not user.is_authenticated %} : ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ํ™•์ธ์ด ์•ˆ๋œ๋‹ค๋ฉด ๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž… ๋…ธ์ถœ

{% else %} : ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ํ™•์ธ์ด ๋œ๋‹ค๋ฉด {{ user.username }} ์œผ๋กœ ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„ ์ •๋ณด ๋…ธ์ถœ

{% endif %} ๋กœ ์กฐ๊ฑด ๋งˆ๋ฌด๋ฆฌ

<!-- templates/base.html -->
<form class="form-inline my-2 my-lg-0">
    {% if not user.is_authenticated %}
        <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
                <a class="nav-link" href="/sign-in"> Sign In <span class="sr-only"></span></a>
            </li>
            <li class="nav-item active">
                <a class="nav-link" href="/sign-up"> Sign Up <span class="sr-only"></span></a>
            </li>
        </ul>
    {% else %}
        {{ user.username }} ๋‹˜ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค!
    {% endif %}
</form>

 

3) ๋กœ๊ทธ์ธ์˜ ํ•„์ˆ˜ ๊ธฐ๋Šฅ ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ์ œํ•œ

- ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ํŒ๋‹จ๊ณผ ํ•ด๋‹นํ•˜๋Š” ์กฐ๊ฑด ์ ์šฉ์„ ์œ„ํ•ด tweet ์•ฑ์˜ views.py ์ˆ˜์ •

user = request.user.is_authenticated ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ

# user/views.py

def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)

        me = auth.authenticate(request, username=username, password=password)  # ์‚ฌ์šฉ์ž ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
        if me is not None:  # ์ €์žฅ๋œ ์‚ฌ์šฉ์ž์˜ ํŒจ์Šค์›Œ๋“œ์™€ ์ž…๋ ฅ๋ฐ›์€ ํŒจ์Šค์›Œ๋“œ ๋น„๊ต
            auth.login(request, me)
            return redirect('/')
        else:
            return redirect('/sign-in')  # ๋กœ๊ทธ์ธ ์‹คํŒจ
    elif request.method == 'GET':
        user = request.user.is_authenticated  # ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ๋˜์–ด ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌ
        if user:  # ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ๋‹ค๋ฉด
            return redirect('/')
        else:  # ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด
            return render(request, 'user/signin.html')

 

4) ๋กœ๊ทธ์ธ ์‹œ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋Š” ๋ถˆํ•„์š”ํ•œ ํŽ˜์ด์ง€์ด๋ฏ€๋กœ ํŽ˜์ด์ง€ ์ ‘๊ทผ์„ ์šฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜ ์ˆ˜์ •

- ๋กœ๊ทธ์ธ ์กฐ๊ฑด ํ•จ์ˆ˜์™€ ๋˜‘๊ฐ™์ด user = request.user.is_authenticated ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ํŒ๋‹จ

# user/views.py

def sign_up_view(request):
    if request.method == 'GET':
        user = request.user.is_authenticated # ๋กœ๊ทธ์ธ ๋œ ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ
        if user: # ๋กœ๊ทธ์ธ์ด ๋˜์–ด์žˆ๋‹ค๋ฉด
            return redirect('/')
        else: # ๋กœ๊ทธ์ธ์ด ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด
            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 = get_user_model().objects.filter(username=username)
            if exist_user:
                return render(request, 'user/signup.html') # ์‚ฌ์šฉ์ž๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋„์›€
            else:
                UserModel.objects.create_user(username=username, password=password, bio=bio)
                return redirect('/sign-in') # ํšŒ์›๊ฐ€์ž…์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™

 

5) ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ

- views.py ๋กœ๊ทธ์•„์›ƒ ํ•จ์ˆ˜ ์ถ”๊ฐ€

@login_requred ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ์šฉ์ž๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ / ๋กœ๊ทธ์•„์›ƒ์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์กฐ๊ฑด

#user/views.py

from django.contrib.auth.decorators import login_required

@login_required
def logout(request):
		auth.logout(request) # ์ธ์ฆ ๋˜์–ด์žˆ๋Š” ์ •๋ณด๋ฅผ ์—†์• ๊ธฐ
    return redirect("/")

- urls.py ์—ฐ๊ฒฐ

# 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'),
    path('logout/', views.logout, name='logout')
]
 

- ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๊ธฐ๋Šฅ์—์„œ ์ถ”๊ฐ€ํ–ˆ๋˜ html ์˜ ํ…œํ”Œ๋ฆฟ ์ถ”๊ฐ€

    {% else %}
        <ul class="navbar-nav mr-auto">
            <li class="nav-item" disabled>
                <span class="nav-link">
                    {{ user.username }} ๋‹˜ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค!
                </span>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="/logout"> ๋กœ๊ทธ์•„์›ƒ </a>
            </li>
        </ul>
    {% endif %}

 

 

๊ฒŒ์‹œ๊ธ€ ์“ฐ๊ธฐ & ์ฝ๊ธฐ & ์‚ญ์ œ

1) ์‚ฌ์ „ home.html ์˜ ๊ฒŒ์‹œ๊ธ€์ด ์ž…๋ ฅ ๋  form ํƒœ๊ทธ์— action ๊ณผ method ๋ฅผ ์‚ฌ์šฉํ•ด django ์˜ url ๋กœ ์—ฐ๊ฒฐ

- method = 'post'

- action = '/tweet/'

<form action="/tweet/" method="post">
    {% csrf_token %}
    <div class="form-group mb-2">
        <textarea class="form-control" style="resize: none" name='my-content' id="my-content"></textarea>
    </div>
    <button type="submit" class="btn btn-primary" style="float:right;">์ž‘์„ฑํ•˜๊ธฐ</button>
</form>

 

2) tweet ์•ฑ์˜ ๊ธ€์“ฐ๊ธฐ views.py ์ˆ˜์ •

user = request.user : ์š”์ฒญ ์‹œ ์ž๋™์ ์œผ๋กœ ์ธ์ฆ ์ถ”๊ฐ€

my_tweet.content = request.POST.get('my-content','') : home.html ์˜ input name ๊ฐ’์ธ my-content ์ •์˜

from .models import TweetModel # ๊ธ€์“ฐ๊ธฐ ๋ชจ๋ธ -> ๊ฐ€์žฅ ์œ—๋ถ€๋ถ„์— ์ ์–ด์ฃผ์„ธ์š”!

def tweet(request):
    if request.method == 'GET':  # ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹์ด GET ๋ฐฉ์‹์ธ์ง€ ํ™•์ธํ•˜๊ธฐ
        user = request.user.is_authenticated  # ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ
        if user:  # ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ์šฉ์ž๋ผ๋ฉด
            return render(request, 'tweet/home.html')
        else:  # ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด
            return redirect('/sign-in')
    elif request.method == 'POST':  # ์š”์ฒญ ๋ฐฉ์‹์ด POST ์ผ๋•Œ
        user = request.user  # ํ˜„์žฌ ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ์šฉ์ž๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
        my_tweet = TweetModel()  # ๊ธ€์“ฐ๊ธฐ ๋ชจ๋ธ ๊ฐ€์ ธ์˜ค๊ธฐ
        my_tweet.author = user  # ๋ชจ๋ธ์— ์‚ฌ์šฉ์ž ์ €์žฅ
        my_tweet.content = request.POST.get('my-content', '')  # ๋ชจ๋ธ์— ๊ธ€ ์ €์žฅ
        my_tweet.save()
				return redirect('/tweet')

 

3) tweet ์•ฑ์˜ views.py GET ํ•จ์ˆ˜ ์ˆ˜์ •

TweetModel() : ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๋ฅผ ๊ฒ€์ฆ ํ•œ ํ›„ ๋ถˆ๋Ÿฌ์ฃผ๋Š” ๊ธฐ๋Šฅ

all_tweet = TweetModel.objects.all().order_by('-created_at') : created_at ์˜ ์—ญ์ˆœ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ฝ”๋“œ

return render(request, 'tweet/home.html', {'tweet': all_tweet}) : tweet/home.html์„ ํ™”๋ฉด์— ๋„์šฐ๋ฉด์„œ {'tweet':all_tweet} ๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด์— ์ „๋‹ฌ

# tweet/views.py

def tweet(request):
    if request.method == 'GET':  # ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹์ด GET ๋ฐฉ์‹์ธ์ง€ ํ™•์ธํ•˜๊ธฐ
        user = request.user.is_authenticated  # ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ
        if user:  # ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ์šฉ์ž๋ผ๋ฉด
            all_tweet = TweetModel.objects.all().order_by('-created_at')
            return render(request, 'tweet/home.html', {'tweet': all_tweet})
        else:  # ๋กœ๊ทธ์ธ์ด ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด
            return redirect('/sign-in')
    elif request.method == 'POST':  # ์š”์ฒญ ๋ฐฉ์‹์ด POST ์ผ๋•Œ
        user = request.user  # ํ˜„์žฌ ๋กœ๊ทธ์ธ ํ•œ ์‚ฌ์šฉ์ž๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
        my_tweet = TweetModel()  # ๊ธ€์“ฐ๊ธฐ ๋ชจ๋ธ ๊ฐ€์ ธ์˜ค๊ธฐ
        my_tweet.author = user  # ๋ชจ๋ธ์— ์‚ฌ์šฉ์ž ์ €์žฅ
        my_tweet.content = request.POST.get('my-content', '')  # ๋ชจ๋ธ์— ๊ธ€ ์ €์žฅ
        my_tweet.save()
        return redirect('/tweet')

 

 

4) ์ž‘์„ฑํ•œ ๊ฒŒ์‹œ๊ธ€์„ ํ™”๋ฉด์ƒ์œผ๋กœ ๋…ธ์ถœ์‹œํ‚ค๊ธฐ

- for ๋ฌธ ๋ฐ˜๋ณต๋ฌธ์˜ html ํ…œํ”Œ๋ฆฟ์— ์ ์šฉ

<!-- templates/tweet/home.html -->
<hr>
<!-- ์ž‘์„ฑ ๋œ ๊ธ€์ด ๋‚˜์˜ค๋Š” ๊ณณ -->
<div class="row">
    {% for tw in tweet %}
        <div class="col-md-12 mb-2">
            <div class="card">
                <div class="card-body">
                    <div class="media">
                        <div class="media-body">
                            <h5 class="mt-0">{{ tw.content }}</h5>
                        </div>
                        <div style="text-align: right">
                            <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} ์ „</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    {% endfor %}
</div>

 

5) ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ ๊ธฐ๋Šฅ

- views.py ์—์„œ ๊ฒŒ์‹œ๊ธ€์˜ ๋ณธ์ธ ์ž‘์„ฑ์ž๋งŒ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋Šฅ์„ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•œ login_required ์ž„ํฌํŠธ

- ํ•จ์ˆ˜์˜ request ์™€ id ๋ฅผ ์ ์šฉํ•ด id ์˜ ํ•ด๋‹นํ•˜๋Š” ์‚ฌ์šฉ์ž๋งŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„

# tweet/views.py
from django.contrib.auth.decorators import login_required


@login_required
def delete_tweet(request, id):
    my_tweet = TweetModel.objects.get(id=id)
    my_tweet.delete()
    return redirect('/tweet')

- urls.py ์—์„œ ์‚ญ์ œ ๊ธฐ๋Šฅ ํ•จ์ˆ˜๋ฅผ ์—ฐ๊ฒฐ : <int:id> ๊ฒŒ์‹œ๊ธ€์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„ ์‚ฌ์šฉ

# tweet/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('tweet/', views.tweet, name='tweet'),
    path('tweet/delete/<int:id>', views.delete_tweet, name='delete-tweet'),
]

- home.html ์— ๊ธ€ ์‚ญ์ œ url ์„ ์—ฐ๊ฒฐ : ์‚ญ์ œ ๋ฒ„ํŠผ์€ /tweet/delete/tw.id ๋กœ ์—ฐ๊ฒฐ์ด ๋˜๋Š”๋ฐ, ์ด tw.id๋Š” ๊ฒŒ์‹œ๊ธ€์˜ ๊ณ ์œ  id๊ฐ’

<!-- templates/tweet/home.html -->
... ์ƒ๋žต 

<!-- ์ž‘์„ฑ ๋œ ๊ธ€์ด ๋‚˜์˜ค๋Š” ๊ณณ -->
<div class="row">
    {% for tw in tweet %}
        <div class="col-md-12 mb-2">
            <div class="card">
                <div class="card-body">
                    {% if tw.author == user %}
                    <div style="text-align: right">
                        <a href="/tweet/delete/{{ tw.id }}">
                            <span class="badge rounded-pill bg-danger">์‚ญ์ œ</span>
                        </a>
                    </div>
                    {% endif %}
										<div style="text-align: right">
										    <a href="#">
										        <span class="badge rounded-pill bg-success">๋ณด๊ธฐ</span>
										    </a>
										</div>
                    <div class="media">
                        <div class="media-body">
                            <h5 class="mt-0">{{ tw.content }}</h5>
                        </div>
                        <div style="text-align: right">
                            <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} ์ „</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    {% endfor %}
</div>

... ์ƒ๋žต

 

 

์ถœ์ฒ˜ ์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ

 
Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.