티스토리 뷰

python/Lecture

python 활용 #8 : django

jinozpersona 2021. 3. 3. 12:20

django : wiki

파이썬으로 작성된 오픈 소스 웹 프레임워크로, 모델-뷰-컨트롤러(MVC) 패턴을 따르고 있다.

- 고도의 데이터베이스 기반 웹사이트를 작성하는 데 있어서 수고를 더는 것이 장고의 주된 목표

- 콤포넌트의 재사용성(reusability)과 플러그인화 가능성(pluggability), 빠른 개발 , "DRY(Don't repeat yourself: 중복배제)" 원리

- 설정 파일부터 데이터 모델에까지 파이썬 언어가 구석구석에 쓰였다.

 

<특징>

0. 구성

 장고는 파이썬으로 코딩한 모델을 관계형 데이터베이스로 구축해주는 모델(Model), HTTP 요청을 처리하는 웹 템플릿 시스템인 뷰(View), URL의 라우팅을 처리하는 URL 컨트롤러 (Controller) 로 구성된 MVC 디자인 패턴을 따른다.

- 전통적인 MVC 디자인 패턴에서 이야기하는 컨트롤러의 기능을 프레임워크를 자체에서 하기 때문에 모델(Model), 템플릿(Template), 뷰(View)로 분류해 MTV 프레임워크라고 보기도 한다.

 

1. 모델 : Model

- 모델은 데이터에 관한 정보를 담는다. 데이터에 대한 접근, 검증, 작동과 데이터 사이의 관계를 정의하는데, 일반적으로 각각의 모델은 데이터베이스에서 테이블에 해당한다.

- 장고에서는 모델을 정의할 때 필드의 종류를 지정해줘야 하는데, 이것이 데이터베이스에게 컬럼 타입을 알려주고 HTML 폼으로 표시 될 때의 입력 타입도 내포하는 역할을 한다. 또한 장고의 폼 자동 생성 API(Application Programming Interface)를 이용할 때 데이터 검증에 쓰이기도 한다.

2. 뷰 : View

- 어떤 데이터가 표시될 것인지를 정의한다. 뷰는 HTTP 응답(response)를 반환해야 하며 응답의 종류는 웹 페이지, 리디렉션, 문서 등의 다양한 형태가 가능하다.

- 장고에는 자주 사용되는 형태의 뷰를 패턴화하여 추상화 해둔 재사용 가능한 뷰들을 내장해 놓았는데, 이들을 제네릭 뷰(generic view) 라고 하며 원하는 제네릭 뷰를 상속한 클래스 뷰를 생성하여 사용할 수 있다.

3. 템플릿 : T

- 데이터가 어떻게 표시되는 지를 정의한다. 템플릿은 사용자에게 실제로 보여지는 웹 페이지나 문서를 다룬다.

- 흔히 HTML 에 기반해서 템플릿을 만들며, HTML 에 동적인 요소를 추가하기 위해 파이썬의 일부 기능을 쓰게 도와주는 장고 템플릿 태그가 존재한다.

 

INTRO

Django는 파이썬으로 구성된 서버-사이드 웹 프레임워크

python을 사용하지만 Django 핵심 개념 이해에 필수는 아님

개발 환경 설정 : Mac OSWindows, Linux(Ubuntu) 운영체제와 Editor(sublimetext, visual studio code, ... )

django-project 생성과 app 생성과 운영을 MVT 흐름에 따른 이해가 중요함 : 뼈대만들기 참고

template(web-page) 구현/구성에 필요한 HTML/CSS/javascript과 bootstrap의 기본 이해가 필요

 

Contents

1. 개발환경 설정 및 django 구동 : 가상환경(pyenv), Editor(SublimeText) REPL 설정

2. django 초기 설정 : settings.py, scret_key 보안설정, superuser 생성

3. App 생성 : models.py, views.py, urls.py, template.html

4. model base ORM 목록보기/디테일보기/생성하기/수정하기/지우기(처음이해하기 / ERP만들어보기)

 

추가 To Do List

- BOOTSTRAP

- Template 구조화 : (1) (2) (3)   

- 인증 : 회원가입, 로그인, 로그아웃

- chart

- csv : ORM : DB

....

 

MVT 흐름 이해하기

1번/2번은 위 포스트를 참고하고 여기서는 3번 app 생성부터 django MVT 흐름을 이해한다.

django MVT

MVT 흐름 이해를 설명하는 좋은 예를 찾아 아래 나타내었다.

MVT 패턴 구조

링크 : https://butter-shower.tistory.com/49

 

django project MVT 패턴 moule 기능

링크 : https://github.com/sakai-memoru/lework/blob/master/docs/1806-django-4th-step.md

 

 

app 생성하기

$ ./manage.py startapp persona

 

app 등록하기
config/settings.py
....

INSTALLED_APPS = [
    'persona.apps.PersonaConfig',
	....
]

 

기본폴더 및 파일 생성

persona/templates/persona/

persona/urls.py

 

Model
persona/models.py
from django.db import models
from django.conf import settings


# Create your models here.
class StaffUser(models.Model):
	person      = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=False, verbose_name='유저')
	staff_code  = models.CharField('스텝번호', max_length=32, unique=True)
	team_name   = models.CharField('소속팀', max_length=64, null=True)
	position    = models.CharField('직급/직위', max_length=64, null=True)

	def __str__(self):
		return self.staff_code

class ProductOrder(models.Model):
	staffuser   = models.ForeignKey(StaffUser, on_delete=models.CASCADE, null=False)
	po_num      = models.CharField('PO번호', max_length=64, null=False)
	po_name     = models.CharField('PO이름', max_length=64, null=False)
	po_qnt      = models.IntegerField('PO수량', default=0)
	po_price    = models.IntegerField('PO단가', default=0)
	po_date     = models.DateTimeField('PO생성일', auto_now_add=True)
	cm_company  = models.CharField('고객사', max_length=64, null=False)
	cm_name     = models.CharField('고객명', max_length=64, null=False)
	dsn_num     = models.CharField('설계번호', max_length=64, null=True)
	ship_date   = models.DateTimeField('출하예정일',auto_now=False)
	ship_order  = models.BooleanField('출하지시',default=False)

	def __str__(self):
		return self.po_num


class ShipOrder(models.Model):
	product_order   = models.ForeignKey(ProductOrder, on_delete=models.CASCADE, null=False)
	so_num          = models.CharField('출하번호', max_length=64, null=False)
	so_qnt          = models.IntegerField('출하수량', default=0)
	shipping_date   = models.DateTimeField('출하일',auto_now=False)
	shipping_status = models.BooleanField('출하상태',default=False)
	
	def __str__(self):
		return self.so_num

persona Person models DB 반영

$ ./manage.py makemigrations persona

 

$ ./manage.py migrate

 

View
persona/admin.py 
from django.shortcuts import render
from persona.models import StaffUser, ProductOrder, ShipOrder


# Create your views here.
def test_board(request):
	staffusers = StaffUser.objects.all()
	product_orders = ProductOrder.objects.all()
	ship_orders = ShipOrder.objects.all()
	ctx = {'staffusers':staffusers, 'product_orders':product_orders, 'ship_orders':ship_orders}
	return render(request, 'persona/test_board.html', ctx)

 

Template
persona/templates/persona/test_board.html
{% load static %}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
        <title>{% block title %}{{ section.title }}{% endblock %}</title>
        <link href="{% static 'css/styles.css' %}" rel="stylesheet" />
    </head>

    <body class="sb-nav-fixed">
        <!-- Topbar -->
        <div id="layoutSidenav">
        <!-- Sidebar -->
            <div id="layoutSidenav_nav">
                <nav class="sb-sidenav accordion sb-sidenav-dark" id="sidenavAccordion">
                    <div class="sb-sidenav-menu">
                        <div class="nav">
                            <a class="nav-link" href="{% url 'persona:test_board' %}">
                                <div class="sb-nav-link-icon"><i class="fas fa-tachometer-alt"></i></div>
                                TestBoard
                            </a>
                            <!-- Report part End-->
                        </div>
                        <!-- End <div class="nav"> -->
                    </div>
                </nav>
            </div>

            <!-- Main_Contents -->
            <div id="layoutSidenav_content">
                <main>
                    <div class="container-fluid px-4">
                        <!-- Main_Header -->
                        <h1 class="mt-4">Persona Test</h1>
                        <!-- Main_content_#1 -->
                        <div class="card mb-4">
                            <div class="card-header">
                                Test Board | <a href="#">글쓰기</a>
                            </div>
                            <div class="card-body">
                                <p>{{ staffusers }}</p>
                                <p>{{ product_orders }}</p>
                                <p>{{ ship_orders }}</p>
                            </div>
                        </div>
                        <!-- Main_content_#2 -->
                        <div class="card mb-4">
                            <div class="card-header">
                                <i class="fas fa-table me-1"></i>
                                Table Test | <a href="#">글쓰기</a>
                            </div>
                            <div class="card-body">
                                <table id="datatablesSimple">
                                    <thead>
                                        <tr>
                                            <th>직원</th>
                                            <th>PO번호</th>
                                            <th>PO이름</th>
                                            <th>PO수량</th>
                                            <th>PO단가</th>
                                            <th>PO생성일</th>
                                            <th>고객사</th>
                                            <th>고객명</th>
                                            <th>설계번호</th>
                                            <th>출하예정일</th>
                                            <th>출하지시여부</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                    {% for po in product_orders %}
                                        <tr>
                                            <td>{{ po.staffuser }}</td>
                                            <td>{{ po.po_num }}</td>
                                            <td>{{ po.po_name }}</td>
                                            <td>{{ po.po_qnt }}</td>
                                            <td>{{ po.po_price }}</td>
                                            <td>{{ po.po_date | date:'Y-m-d' }}</td>
                                            <td>{{ po.cm_company }}</td>
                                            <td>{{ po.cm_name }}</td>
                                            <td>{{ po.dsn_num }}</td>
                                            <td>{{ po.ship_date | date:'Y-m-d' }}</td>
                                            <td>{{ po.ship_order }}</td>
                                        </tr>
                                    {% endfor %}
                                    </tbody>
                                </table>
                            </div>
                        </div>
                        <!-- Main_content_#3 -->

                        <!-- Main_content_#4 -->

                    </div>
                </main>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" crossorigin="anonymous"></script>
        <script src="{% static 'js/datatables-simple-demo.js' %}"></script>
    </body>
</html>

 

CSS : bootstrap 이용
static/css/style.css
아래 링크 다운로드 후 style.css 적용
https://startbootstrap.com/template/sb-admin
@charset "UTF-8";
/*!
* Start Bootstrap - SB Admin v7.0.4 (https://startbootstrap.com/template/sb-admin)
* Copyright 2013-2021 Start Bootstrap
* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-sb-admin/blob/master/LICENSE)
*/
/*!
 * Bootstrap v5.1.3 (https://getbootstrap.com/)
 * Copyright 2011-2021 The Bootstrap Authors
 * Copyright 2011-2021 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 */
:root {
  --bs-blue: #0d6efd;
  --bs-indigo: #6610f2;
  
  ....

 

URL
config/urls.py
from django.contrib import admin
from django.urls import path, include
from persona import urls


urlpatterns = [
    path('admin/', admin.site.urls),

    path('persona/', include("persona.urls")),
]

 

Router
persona/urls.py
from django.urls import path
from persona import views

app_name = 'persona'

urlpatterns = [
    path('test_board/', views.test_board, name='test_board'),
]

 

---------------------- html page 확인 ----------------------

http://localhost:8000/admin/ 접속 후 board 3종 StaffUser, ProductOrder, ShipOrder 작성 후 확인 가능

http://localhost:8000/persona/test_board/

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함