본문 바로가기
개발일지/Django

Django - 기본사이클 - 모델과 웹사이트2

by 개발에정착하고싶다 2022. 9. 30.
320x100

# django 모델과 웹사이트 1에 이은 2편을 시작한다.


#1

 

만들어두었던 어플리케이션 안의 models.py

를 열고 클래스를 만들어주자.

 

나는 경로가

 

my_car_site > cars > models.py

이다.

from django.db import models

# Create your models here.
class Car(models.Model):
    # primary key가 auto increment방식으로 늘어간다.
    brand = models.CharField(max_length=30)
    year = models.IntegerField()
    
    def __str__(self):
        return f'Car is {self.brand} {self.year}'

#2

 

 

manage.py가 있는 경로의 터미널에서

 

python manage.py makemigrations cars

라고 입력한다.

 

그러면 어플리케이션 안에 migration 폴더가 생성된다.


#3

 

이어서

 

python manage.py migrate

를 터미널에 입력


#4

 

다시 어플리케이션 안의 views.py

파일로 돌아온다.

 

코드를

from django.shortcuts import render
from . import models

# Create your views here.

def list(request):
    all_cars = models.Car.objects.all()
    context = {'all_cars':all_cars}
    
    return render(request, 'cars/list.html', context = context)

def add(request):
    return render(request, 'cars/add.html')

def delete(request):
    return render(request, 'cars/delete.html')

이렇게 수정해주고


#5

 

어플리케이션 안의 templates 폴더 안의 cars 폴더 안의 list.html로 돌아간다.

 

코드를 이렇게 수정해준다.

{% extends 'base.html' %}

{% block content  %}
<div class='container'>
    <h1>LIST</h1>
        <ul>
            {% for car in all_cars %}
                <li>{{car}}</li>
            {% endfor %}
        </ul>
</div>

{% endblock  %}

여기서 말하는 all_cars는 4번에 해당하는 views.py에 정의된 내용을 의미한다.


#6

 

그 다음엔 5번의 list.html이 있던 동일한 위치의 add.html로 들어가자

 

코드를 이렇게 해준다.

{% extends 'base.html' %}

{% block content  %}
<div class="container">
    <h1>ADD</h1>
    <h2>Add a new car to the database:</h2>
    <form action="" method='POST'>
        <div>
            <label for="brand">Brand:</label>
            <input type="text" id='brand' name='brand'>
        </div>
        <div>
            <label for="">Year:</label>
            {% comment %} 이부분에 id가 아닌 is로 들어간게 의아하다. {% endcomment %}
            <input type="text" is='year' name='year'>
        </div>
        <input type="submit">

    </form>
</div>

{% endblock  %}

그리고 python manage.py runserver

로 열고

주소값을

http://127.0.0.1:8000/cars/add/

로 확인해준다.

페이지가 나오면 정상적으로 작동하는 것이다.

 

그리고 거기의 Brand란에다가 문자

Year에 숫자를 넣고 ‘제출’ 혹은 ‘submit’버튼을 누르게 되면

Forbidden (403)

라고 에러가 뜬다.

그리고 바로 밑에

CSRF ~~ 라고 뜨는데

이것은 해킹을 방지하기 위한 보안장치라고 보면된다.


#7

 

6번의 페이지를 보다보면

{% csrf_token %}

라는게 있는데, 그것과 style요소들을 코드에 적용시킨 것을 6번의 add.html에 이어서

코드 수정해주자.

{% extends 'base.html' %}

{% block content  %}
<div class="container">
    <h1>ADD</h1>
    <h2>Add a new car to the database:</h2>
    <form action="" method='POST'>
        {% comment %} 해킹 시도가 아닙니다. 라는 메세지를 django에게 알려주는 것 {% endcomment %}
        {% csrf_token %}
        <div class='form-group'>
            <label for="brand">Brand:</label>
            <input class='form-control' type="text" id='brand' name='brand'>
        </div>
        <div class='form-group'>
            <label for="">Year:</label>
            {% comment %} 이부분에 id가 아닌 is로 들어간게 의아하다. {% endcomment %}
            <input class='form-control' type="text" is='year' name='year'>
        </div>
        <input class='btn btn-primary' type="submit">

    </form>
</div>

{% endblock  %}

#8

 

다시 4번의 views.py 로 이동

 

코드작성을 이렇게

from django.shortcuts import render, redirect
from django.urls import reverse
from . import models

# Create your views here.

def list(request):
    all_cars = models.Car.objects.all()
    context = {'all_cars':all_cars}

    return render(request, 'cars/list.html', context = context)

# 이 코드의 전체적 의미는 사용자가 POST방식, 즉 데이터를 직접 입력하는 것이면 if문을 따르고,
# 그 외의 경우는 그냥 add.html을 렌더링 한다는 의미다.
def add(request):
    # 이것은 사실상 POST방식, 즉, 사용자가 (여기서는 add함수 내부니깐) add 페이지에서
    # 데이터를 입력하면 해당 데이터를 print는 확인할 수 있는 것이고, 이 코드를 수정해주면 저장하여 누적도 가능하다.

    if request.POST:
        brand = request.POST['brand']
        year = int(request.POST['year'])
        models.Car.objects.create(brand=brand, year=year)
        # if user submitted new car ==> list.html
        return redirect(reverse('cars:list'))
    else:
        return render(request, 'cars/add.html')

def delete(request):
    return render(request, 'cars/delete.html')

#9

 

이젠 바로 옆의 delete.html로 이동해준다.

 

코드는 이렇다

{% extends 'base.html' %}

{% block content  %}
<div class="container">
    <h1>DELETE.HTML</h1>
    <h1>Enter pk to delete car!</h1>

    <form action="" method="POST">

        {% csrf_token %}
            <div class='form-group'>
                <label for='pk'>PK number:</label>
                <input class='form-control' type='text' id='pk' name='pk'>
            </div>
            <input class='btn btn-primary' type='submit'>

    </form>

</div>
<h1>DELETE</h1>
{% endblock  %}

#10

 

다시 어플리케이션 안의 views.py로 돌아온다.

코드는 이렇다

 

from django.shortcuts import render, redirect
from django.urls import reverse
from . import models

# Create your views here.

def list(request):
    all_cars = models.Car.objects.all()
    context = {'all_cars':all_cars}

    return render(request, 'cars/list.html', context = context)

# 이 코드의 전체적 의미는 사용자가 POST방식, 즉 데이터를 직접 입력하는 것이면 if문을 따르고,
# 그 외의 경우는 그냥 add.html을 렌더링 한다는 의미다.
def add(request):
    # 이것은 사실상 POST방식, 즉, 사용자가 (여기서는 add함수 내부니깐) add 페이지에서
    # 데이터를 입력하면 해당 데이터를 print는 확인할 수 있는 것이고, 이 코드를 수정해주면 저장하여 누적도 가능하다.

    if request.POST:
        brand = request.POST['brand']
        year = int(request.POST['year'])
        models.Car.objects.create(brand=brand, year=year)
        # if user submitted new car ==> list.html
        return redirect(reverse('cars:list'))
    else:
        return render(request, 'cars/add.html')

def delete(request):
    if request.POST:
        # delete the car
        pk = request.POST['pk']
        try:
            models.Car.objects.get(pk=pk).delete()
            # 삭제 후에 어플리케이션 cars의 list로 리디렉션 한다는 뜻
            return redirect(reverse('cars:list'))
        except:
            print('pk not found')
            return redirect(reverse('cars:list'))
    else:
        return render(request, 'cars/delete.html')

 

그 이후로는 사실상

테스트의 영역이다.

 

add 에서는 POST방식으로 데이터를 입력하는 것이고

add에서 데이터를 입력할때마다 auto increment 방식으로써

primary key가 1개씩 자동으로 절대값으로써 증가하고

 

delete에서는 pk값을 입력하게되면 삭제가 되고

삭제 후에 list로 리디렉트 된다.

 

delete시엔 2가지 특징이 있는데

첫째로는 pk값은 절대값이여서 1,2번이 있을때 1번을 없애고 데이터가 1개가 남았다고 해서

나머지 1개가 1번이 되는게 아니다. 나머지 1개도 이미 고유한 pk값이 2번으로 부여되었기 때문에

해당 pk넘버는 2이다.

 

두번째로는 만약 pk값이 없는것을 삭제요청한다면

백단에서 pk not found라는 메세지가 뜨게끔 셋팅해두었다.

 

-끗

300x250