IT 툴툴

[Django파이썬웹프로그래밍] 05 실습 예제 확장하기 - 5.1

은듄 2021. 11. 27. 00:49
반응형

 

3장에서의 예제를 확장하여 클래스형 뷰를 사용하는 애플리케이션(4장 내용 추가)을 만들어봐요!

 


5.1 새로운 애플리케이션 만들기


books 애플리케이션 개발.

 

출판에 필요한 정보들인 책, 저자, 출판사에 대한 정보들을 관리하는 앱 애플리케이션

 

5.1.1 애플리케이션 설계하기

 

아래의 UI 설계를 보자!

[그림05_01] Book 애플리케이션 - UI 설계

 

5.1.2 프로젝트 뼈대 만들기 - 애플리케이션 추가

 

# cd 프로젝트폴더

python manage.py startapp books		# books 명의 애플리케이션 디렉토리 생성

 

[그림05_02] book 애플리케이션 디렉토리 생성

추가한 애플리케이션을 프로젝트에서 사용하려면 setting.py 파일에 등록해야 한다.

 

# cd 프로젝트폴더/settings.py

# 위에 내용 동일

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls.apps.PollsConfig',
    'books.apps.BooksConfig',	# Books 애플리케이션 설정 등록

]

# 위에 내용 동일

 

5.1.3 애플리케이션 - Model 코딩하기

 

Book(책), Author(저자), Publisher(출판사) Model을 각각 만들자

# cd 프로젝트폴더/books/models.py

from django.db import models


class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField('Author')
    publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)	
    	# CASCADE : Publisher 테이블의 레코드 삭제시 연결된 Book 레코드가 삭제됨
    publication_date = models.DateField()

    def __str__(self):
        return self.title


class Author(models.Model):
    name = models.CharField(max_length=50)
    salutation = models.CharField(max_length=100)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Publisher(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=100)
    website = models.URLField()

    def __str__(self):
        return self.name

테이블 관계 필드는 ForeignKey(N:1), ManyToManyField(N:N), OneToOneField(1:1) 3가지로 나타낸다.

 

다음은 admin 페이지에서 사용할 수 있게 정의한 모델들을 추가한다.

# cd 프로젝트폴더/books/admin.py

from django.contrib import admin
from books.models import Book, Author, Publisher


admin.site.register(Book)
admin.site.register(Author)
admin.site.register(Publisher)

 

추가한 Model 정보로 DB 마이그레이션 하기

 

# In Terminal

python manage.py makaemigrations
python managy.py migrate

python manage.py runserver

 

[그림05_03] 추가한 Model 정보로 DB 마이그레이션 터미널 수행 결과 

dmin 사이트에서 추가된 Books 모델 페이지 확인하기

[그림05_04] admin 사이트에서 추가된 BOOKS 모델 페이지 확인

 

5.1.4 애플리케이션 - URLconf 코딩하기

 

설계한 URL패턴을 기반으로 설정

# cd 프로젝트폴더/books/urls.py ( 신규 생성해야함 )

from django.urls import path
from . import views


app_name = 'books'
urlpatterns = [
    # /books/
    path('', views.BooksModelView.as_view(), name='index'),

    # /books/book/
    path('book/', views.BookList.as_view(), name='book_list'),

    # /books/author/
    path('author/', views.AuthorList.as_view(), name='author_list'),

    # /books/publisher/
    path('publisher/', views.PublisherList.as_view(), name='publisher_list'),

    # /books/book/99/
    path('book/<int:pk>/', views.BookDetail.as_view(), name='book_detail'),

    # /books/author/99/
    path('author/<int:pk>/', views.AuthorDetail.as_view(), name='author_detail'),

    # /books/publisher/99/
    path('publisher/<int:pk>/', views.PublisherDetail.as_view(), name='publisher_detail'),
]

 

추가로 만든 Books 애플리케이션 용 URLconf 파일을 프로젝트 urls.py 설정에 추가한다.

# cd 프로젝트폴더/urls.py 

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

#from django.urls import path
#from polls import views

urlpatterns = [
    path('admin/', admin.site.urls),	# 이전과 동일

    path('polls/', include('polls.urls')),	# 이전과 동일
    
    path('books/', include('books.urls')),	# /books/urls.py 사용 추가
   
    # 이전과 동일
]

 

5.1.5 애플리케이션 - 클래스형 View 코딩하기

 

URLconf 설정한 as_view() 메소드를 통한 클래스형 뷰를 코딩한다

# cd 프로젝트폴더/books/views.py 

from django.views.generic.base import TemplateView
from django.views.generic import ListView
from django.views.generic import DetailView
from books.models import Book, Author, Publisher


#--- TemplateView
class BooksModelView(TemplateView):
    template_name = 'books/index.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['model_list'] = ['Book', 'Author', 'Publisher']
        return context


#--- ListView
class BookList(ListView):
    model = Book


class AuthorList(ListView):
    model = Author


class PublisherList(ListView):
    model = Publisher


#--- DetailView
class BookDetail(DetailView):
    model = Book


class AuthorDetail(DetailView):
    model = Author


class PublisherDetail(DetailView):
    model = Publisher

 

 

5.1.6 애플리케이션 - Template 코딩하기

 

# cd 프로젝트폴더/books/templates/books/index.html

{% extends "base_books.html" %}

{% block content %}
    <h2>Books Management System</h2>
    <ul>
        {% for modelname in model_list %}
{% with "books:"|add:modelname|lower|add:"_list" as urlvar %}
            <li><a href="{% url urlvar %}">{{ modelname }}</a></li>
{% endwith %}
        {% endfor %}
    </ul>
{% endblock content %}

 

 

# cd 프로젝트폴더/books/templates/books/book_list.html

{% extends "base_books.html" %}

{% block content %}
    <h2>Book List</h2>
    <ul>
        {% for book in object_list %}
            <li><a href="{% url 'books:book_detail' book.id %}">{{ book.title }}</a></li>
        {% endfor %}
    </ul>
{% endblock content %}
# cd 프로젝트폴더/books/templates/books/book_detail.html

{% extends "base_books.html" %}

{% block content %}

<h1>{{ object.title }}</h1>
<br>
<li>Authors: 
{% for author in object.authors.all %}
  {{ author }}
  {% if not forloop.last %},{% else %}{% endif %}
{% endfor %}
</li>

<li>Publisher: {{ object.publisher }}</li>
<li>Publication date: {{ object.publication_date }}</li>

{% endblock content %}

 

# cd 프로젝트폴더/books/templates/books/author_list.html

{% extends "base_books.html" %}

{% block content %}
    <h2>Author List</h2>
    <ul>
        {% for author in object_list %}
            <li><a href="{% url 'books:author_detail' author.id %}">{{ author.name }}</a></li>
        {% endfor %}
    </ul>
{% endblock content %}
# cd 프로젝트폴더/books/templates/books/author_detail.html

{% extends "base_books.html" %}

{% block content %}

<h1>{{ object.name }}</h1>
<p>{{ object.salutation }}</p>
<li>Email: {{ object.email }}</li>

{% endblock content %}

 

 

# cd 프로젝트폴더/books/templates/books/publisher_list.html

{% extends "base_books.html" %}

{% block content %}
    <h2>Publisher List</h2>
    <ul>
        {% for publisher in object_list %}
            <li><a href="{% url 'books:publisher_detail' publisher.id %}">{{ publisher.name }}</a></li>
        {% endfor %}
    </ul>
{% endblock content %}
# cd 프로젝트폴더/books/templates/books/publisher_detail.html

{% extends "base_books.html" %}

{% block content %}

<h1>{{ object.name }}</h1>
<p>{{ object.website }}</p>
<li>Address: {{ object.address }}</li>

{% endblock content %}

 

위 7개 파일 추가 후 아래의 settings의 template 디렉토리 인식 설정 확인

 

# cd 프로젝트폴더/settings.py

...

TEMPLATES = [
    {
        ...
        
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        
       	...
    },
]

...

 

5.1.7 애플리케이션 - Template 상속 기능 추가

 

상속할 base.html Template 을 추가한다.

# cd 프로젝트폴더/templates/base.html

<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <link rel="stylesheet" href="{% static 'admin/css/base.css' %}" />
    <title>{% block title %}My Amazing Site{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Project_Home</a></li>
            <li><a href="/admin/">Admin</a></li>
        </ul>
        {% endblock %}
        <br>
    </div>

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

books 애플리케이션의 상속할 base_books.html Template 파일도 작성한다.

# cd 프로젝트폴더/templates/base_books.html

{% extends "base.html" %}

{% block title %}Books Application Site{% endblock %}

{% block sidebar %}
{{ block.super }}
<ul>
    <li><a href="/books/">Books_Home</a></li>
</ul>
{% endblock %}

 

5.1.8  지금까지 작업 확인하기

 

[그림05_05] books 메인 페이지

 

그롬 여기까지 하자! 고생하셨슴다~

반응형