[Django] 장고의 구성 요소

MINJEE·2023년 12월 14일

SMHRD_7_Django

목록 보기
3/8
post-thumbnail

장고의 구성요소

◉ 프로젝트 (project)

: 웹 애플리케이션의 전체적인 구조를 담당하는 최상위 수준의 구성 요소
  • 여러 앱(app)을 포함
  • 설정파일, URLconf, 정적 파일, 데이터베이스 설정 등 관리

장고 프로젝트 생성

  1. 장고 프로젝트의 루트 디렉토리 생성 후, 그 디렉토리에서 가상환경 실행
  2. 장고 프로젝트를 수행할 디렉토리 생성 후, 장고 프로젝트 생성
  3. 개발 서버 구동 후 웹 사이트 접속
  • django-admin startproject config . : 장고 프로젝트 생성
    • 맨 뒤의 온점(.)은 현재 디렉토리를 기준으로 장고 프로젝트를 생성한다는 의미
  • python manage.py runserver : 장고 프로젝트 구동

윈도우에서 프로젝트 생성

  1. 'django_workspace'라는 이름의 루트 디렉토리 생성 후 이동
    > cd \
    > mkdir django_workspace
    > cd django_workspace
  2. 'mysite' 가상환경에 진입
    \django_workspace> C:\virtual\mysite\Scripts\activate
  3. 'proj' 디렉토리 생성 후 이동
    (mysite)\django_workspace> mkdir proj
    (mysite)\django_workspace> cd proj
  4. 장고 프로젝트 생성
    (mysite) \django_workspace\proj> django-admin startproject config .
  5. proj 구동
    (mysite) \django_workspace\proj> python manage.py runserver

맥에서 프로젝트 생성

  1. 'django_workspace' 루트 디렉토리 생성 후 이동
    (base) % mkdir django_workspace
    (base) % cd django_workspace
  2. 가상환경 실행
    (base) django_workspace % source 가상환경 경로/bin/activate
  3. 장고 프로젝트 생성 후 구동
    (mysite) (base) django_workspace % mkdir proj
    (mysite) (base) django_workspace % cd proj
    (mysite) (base) proj % django-admin startproject config .
    (mysite) (base) proj % python manage.py runserver

서버 구동 결과

  • 개발 서버 구동시킨 페이지 결과
  • cmd/터미널에서 구동 결과의 마지막 부분
    • 장고 개발 서버가 http://127.0.0.1:8000/으로 시작되었다는 것과 서버를 중지시키기 위해 CONTROL-C를 입력하라는 내용


◉ 앱 (app)

: 프로젝트에 기능을 추가하기 위한 요소
  • 특정 기능 또는 업무를 수행하는 독립적인 모듈
  • 각 앱은 모델, 뷰, 템플릿, URLconf 등 포함
  • 장고는 이러한 앱들을 조합하여 웹 애플리케이션 구성
  • django-admin startapp 앱이름 : 앱 생성
    • 윈도우 : 'app1'이라는 앱 생성
      (mysite) \django_workspace\proj> django-admin startapp app1
      • 프로젝트 폴더 안에 'app1'이라는 폴더가 생성되어 있음


◉ URLconf

: URL과 뷰를 연결하는 역할
  • 장고 프로젝트 내의 URL 패턴과 해당 패턴에 매칭되는 뷰를 연결
  • 웹 애플리케이션의 다양한 기능과 페이지를 URL에 따라 구분하여 처리 가능
  • 일반적으로 프로젝트의 최상위 URLconf와 각 앱(App)의 URLconf로 구성

프로젝트의 URLconf

  • 프로젝트의 최상위 URLconf는 config/urls.py 파일에 위치
  • 프로젝트의 전반적인 URL 패턴을 정의하고, 각 앱의 URLconf와 연결하는 역할
# proj/config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
	path('admin/', admin.site.urls),
    
    # path('앱명/', include('앱명.urls'),
	path('app1/', include('app1.urls')),
	# 다른 앱의 URLconf도 추가할 수 있음
]
  • django.contrib.admin 라이브러리 : 장고의 기본 관리자 사이트를 위한 URL 패턴을 추가
  • django.urls.path 함수 : URL 패턴을 정의
  • include('app1.urls')는 'app1' 앱의 URLconf를 가져와서 해당 URL 패턴을 추가
    → 'app1.urls'은 'app1' 앱의 urls.py 파일을 가리킴
    → 'app1' 앱의 URL 패턴이 app1/ 경로로 시작하는 모든 요청과 연결됨

앱의 URLconf

  • 각 앱은 자체적인 URLconf를 가질 수 있음
  • 앱이름/urls.py 에 위치
  • 앱의 URLconf는 앱 디렉토리 내에 urls.py 파일을 따로 생성해야 함
  • 이 파일은 해당 앱의 특정 기능에 대한 URL 패턴과 뷰를 정의
# proj/app1/urls.py
from django.urls import path
from . import views

# app_name = '앱명'
app_name = 'app1' # 앱 이름 등록

urlpatterns = [
	# path("'앱명/'다음에 오는 경로", views.함수명, name='url별칭'),
	path("", views.index, name='index'), # URL이 app1/
	
    ############### GET방식 공부 ###############
    path("add", views.add), # url이 app1/add 인 경우인 경우
    path("sub/<int:x>/<int:y>", views.sub), # url이 app1/sub/x/y 인 경우
    
    ############### 템플릿 파일 관련 공부 ###############
    path('list', views.list, name = 'list'), # url별칭을 list로 지정
    path('write', views.write),
    path('save', views.save),
    # 다른 URL 패턴과 뷰를 추가할 수 있음
]
  • " " 인 이유 : config/urls.py 파일에서 이미 app1/로 시작하는 URL이 app1/urls.py 파일과 매핑되었기 때문
    ⇒ 즉, config/urls.py 파일에서 매핑된 "app1/" 와 app1/urls.py 파일에서 매핑된 ""이 더해져 "app1/" 완성
  • django.urls.path 함수 : URL 패턴을 정의
  • views.함수명 : 해당 URL 패턴에 대한 처리를 담당하는 뷰 함수 또는 클래스를 가리킴
    • 같은 앱 디렉토리 내의 views.py 파일에 정의된 뷰 함수 또는 클래스
  • name='url별칭' : 해당 URL 패턴에 대한 이름(url별칭)을 지정
    → name에 지정한 이름으로 템플릿이나 코드에서 해당 URL을 참조 가능

url 매핑을 분리하는 이유
: 앱에 관한 URL 매핑을 추가할 때마다 config/urls.py 파일(프로젝트 성격의 파일)을 수정해야하는 것을 예방



◉ 뷰 (view)

: 웹 요청을 처리하고 응답을 생성하는 역할
  • 일반적으로 함수 또는 클래스로 작성
  • 요청을 받아 처리한 후 템플릿을 렌더링하여 사용자에게 보여줌
  • 뷰는 URLconf와 연결되어 특정 URL 패턴에 대한 요청을 처리
  • views.py 파일은 각 앱(App)마다 존재
# proj/app1/views.py
from django.shortcuts import render # html과 연동할 때 사용
from django.shortcuts import redirect # 특정 페이지로 이동할 때 사용
from django.http import HttpResponse  # 요청에 대한 응답할 때 사용

# URL이 'app1/' 인 경우
def index(request):
    return HttpResponse("Hello Django") # 문자열을 브라우저에 출력

############### GET방식 공부 ###############
# URL이 'app1?x=1&y=2' 인 경우 (Get방식, 쿼리스트링)
def add(request):
    x = int(request.GET.get('x'))
    y = int(request.GET.get('y'))
    response = HttpResponse(f"{x} + {y} = {x+y}")
    return response
    
# URL이 'app1/sub/3/4' 인 경우 (Get방식, 경로변수)
def sub(request, x, y):
    result = f"{x} - {y} = {x-y}"
    response = HttpResponse(result)
    return response

############### 템플릿 파일 관련 공부 ###############
personList = [
    {'id':0, 'name':'김민지', 'phone':'010-2900-4039'},
    {'id':1, 'name':'김은지', 'phone':'010-4055-4039'},
]
# URL이 'app1/list'인 경우 (render함수, 템플릿 파일 연동)
def list(request):
    data = {'dataList':personList}
    return render(request, 'app1/person_list.html', data) # 탬플릿(html)파일과 연동

# URL이 'app1/write'인 경우 (render함수, 템플릿 파일 연동)
def write(request):
	# 보낼 데이터가 없다면 생략 가능
    return render(request, 'app1/person_write.html') 

# URL이 'app1/save'인 경우 (redirect함수, 특정 페이지로 이동)
def save(request): 
    name = request.POST.get('name')
    phone = request.POST.get('phone')
    personList.append({'name':name, 'phone':phone})
    return redirect('app1:list') # 'app1/list'URL로 이동
  • HttpResponse함수 : 간단한 텍스트 응답을 생성
  • request.GET.get('파라미터이름') : GET 파라미터의 값을 가져올 수 있음 (쿼리스트링의 경우에 해당)
  • render함수 : 파이썬 데이터를 템플릿에 적용하여 html로 반환하는 함수
    • render(request, '템플릿 파일명', context={데이터이름:값}) : 파이썬 데이터를 템플릿에 적용하여 html로 반환하는 함수
      • 템플릿 파일은 템플릿 디렉토리 내의 '앱이름/html문서이름.html' 파일을 의미
      • 데이터는 딕셔너리 형태로 {’html에서 사용할 데이터명’ : 실제 데이터}
  • redirect함수 : 특정 페이지로 이동시키는 함수
    • redirect(’앱명:url별칭’)
      • [앱명/urls.py] 파일에서 앱명은 app_name = '앱명' 을 통해 등록해 줘야 하고, url별칭은 path(’’, views.함수명, name=’url별칭’) 의 name 으로 지정해줘야 함


◉ 템플릿 (template)

: 템플릿은 사용자에게 보여지는 웹 페이지의 모습을 정의하는 데 사용
  • HTML 코드에 장고의 템플릿 언어(Template Language)를 이용하여 동적으로 데이터를 삽입하고, 반복문, 조건문 등을 사용
  • 뷰에서 전달된 데이터를 받아 사용자에게 동적인 웹 페이지를 보여주는 역할
  • 확장자는 .html이 일반적으로 사용

사전 작업1 : 템플릿 디렉토리 생성

: 프로젝트 디렉토리(proj) 안에 템플릿 파일을 저장할 템플릿 디렉토리(templates) 생성
→ 템플릿 디렉토리 안에 앱이름과 같은 디렉토리 생성 후, 그 안에 템플릿 파일을 생성

  • 템플릿 파일 생성 위치 예시
    : django_workspace(루트 디렉토리명)/proj(프로젝트 디렉토리명)/templates/app1(앱명)/템플릿파일

사전 작업2 : 설정 파일 수정

  • TEMPLATES 의 'DIRS'항목 수정
  • DIRS는 추가적인 템플릿 디렉터리 경로를 설정하는 옵션
# config/settings.py
(생략)
import os
(생략)
TEMPLATES = [
	{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    'APP_DIRS': True,
    'OPTIONS': {
    	'context_processors': [
        	'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',
            'django.contrib.messages.context_processors.messages',
    	],
    },
	},
]
(생략)
  • os.path.join(BASE_DIR, 'templates')는 templates 디렉터리의 절대 경로를 반환
    • BASE_DIR은 settings.py 파일에서 이미 정의된 프로젝트의 기본 경로
      (C:\django_workspace\proj)

탬플릿 언어

  • {{ 변수 }} : 변수 출력

  • {{ 객체.속성 }} : 객체의 속성 값 출력

  • {% 템플릿 태그 %} : 템플릿 태그 작성

    • 조건문, 반복문, 변수 할당 등 다양한 로직을 템플릿 태그를 사용하여 작성
    • 조건문
      {% if 조건1 %}
        실행할 코드
      {% elif 조건2 %}
        다른 조건일 때 실행할 코드
      {% else %}
        모든 조건이 거짓일 때 실행할 코드
      {% endif %}
    • 반복문
      {% for 변수 in 반복_대상 %}
        반복할 코드
      {% empty %}
        반복 대상이 비어있을 때 실행할 코드
      {% endfor %}
    • 변수 할당
      {% 변수명 = 값 %}
    • 템플릿 상속 : 자식 템플릿은 부모 템플릿을 확장하여 필요한 내용을 추가하거나 변경
      {% extends "부모_템플릿" %}
    • 블록 정의 : 템플릿 상속에서 사용되며, 자식 템플릿에서 부모 템플릿의 블록을 재정의할 때 사용
      {% block 블록_이름 %}
        블록 내용
      {% endblock %}

      블록 정의 예시
      부모 템플릿

      <!DOCTYPE html>
      <html>
      <head>
       <title>{% block title %}기본 제목{% endblock %}</title>
      </head>
      <body>
       <header>
           {% block header %}
           <h1>기본 헤더</h1>
           {% endblock %}
       </header>
       <main>
           {% block content %}
           <p>기본 내용</p>
           {% endblock %}
       </main>
       <footer>
           {% block footer %}
           <p>기본 푸터</p>
           {% endblock %}
       </footer>
      </body>
      </html>

      자식 템플릿

      {% extends "parent.html" %}
      
      {% block title %}새로운 제목{% endblock %}
      
      {% block header %}
        <h1>새로운 헤더</h1>
      {% endblock %}
      
      {% block content %}
        <p>새로운 내용</p>
        <p>추가적인 내용</p>
      {% endblock %}
  • {{ 변수|필터 }} : 변수의 값을 특정한 방식으로 변환하여 출력할 때 사용하는 필터

    • ex. {{ name|upper }}는 name 변수의 값을 대문자로 변환하여 출력
  • {# 주석 내용 #} : 주석

    • 렌더링되는 HTML에 포함되지 않으며, 주로 코드 설명이나 작업 기록에 사용

템플릿 파일

<!-- templates/app1/person_list.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Person list</h1>
  <ul>
      {% for person in dataList %}
          <li>{{person.name}} {{person.phone}}</li>
      {% endfor %}
  </ul>
</body>
</html>
<!-- templates/app1/person_write.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <form method="post" action="/app1/save"> 
		<!-- post방식으로 서버에 전송하고 전송된 정보를 받아서 /app1/save 처리 -->
      {% csrf_token %} <!-- post방식으로 데이터 보낼 때 반드시 필요 -->
      이름 : <input type="text" name="name"> <br>
      전화번호 : <input type="text" name="phone"> <br>
      <button type="submit">등록</button>
  </form>
</body>
</html>


◉ 모델 (model)

: 데이터베이스의 테이블과 대응되는 개념으로, 데이터의 구조를 정의하고 데이터베이스와의 상호작용을 처리
  • 장고의 ORM(Object-Relational Mapping)을 통해 데이터베이스와 연결되어 데이터를 조회, 생성, 수정, 삭제할 수 있는 기능을 제공

사전 작업 : 설정 파일 수정

  • [config/settings.py] 파일의 INSTALLED_APPS 항목에 앱 추가
    # config/settings.py
    (생략)
    INSTALLED_APPS = [
    	"앱명.apps.앱명Config", # 앱을 등록해야 Model객체 생성 가능
      	(생략)
    ]
    • 앱명.apps.앱명Config 클래스 : [앱명/apps.py] 파일(앱 생성 시 자동 생성되는 파일)에 있는 클래스 (ex. app1.apps.app1Config)

모델 정의

  • [앱명/models.py] 파일에 모델 클래스 정의

    • 클래스 이름은 주로 단수형으로 사용하며, models.Model 클래스를 상속받아야 함
    • 모델 클래스의 속성으로 필드를 정의
    • 필드는 데이터베이스 테이블의 열에 해당하며, 각 필드는 데이터 타입과 제약 조건을 정의
    • 필요에 따라 모델 클래스에 메서드를 추가 → 데이터를 조작하거나 특정 로직을 수행하는 데 사용
    # 앱명/models.py
    from django.db import models
    
    class 모델_클래스명(models.Model):
      속성1 = models.CharField('객체명', max_length=n) # 길이가 제한된 텍스트 속성
      속성2 = models.TextField('객체명') # 길이 제한 없는 텍스트 속성
      속성3 = models.DateTimeField() # 날짜,시간 관련 속성
      속성4 = models.IntegerField() # 정수 속성
  • python manage.py makemigrations : 필요한 쿼리를 생성

    • 모델 생성/수정이 있을 경우 실행해야 하는 명령
    • [앱명/migrations/0001_initial.py] 파일이 자동 생성
  • python manage.py sqlmigrate 앱명 일련번호 : 실행되는 쿼리를 확인 (수행x)

    • ex. 'app1' 앱에서 생성된 작업파일이 0001_initianl.py 이면, python manage.py sqlmigrate app1 0001 실행
  • python manage.py migrate : 테이블 생성

장고 셀 로 모델 사용하기

Django Shell : Django 환경에서 Python 인터프리터를 실행하는 대화형 콘솔

  • python manage.py shell : 장고 셀 실행
  • >>> from 앱명.models import 모델명 : 정의한 모델 클래스 불러오기

  • >>> 모델명.objects.all() : 모델의 모든 데이터를 조회
    • 쿼리셋(QuerySet) 형태로 반환
  • >>> 모델명.objects.filter(조건) : 조건을 만족하는 데이터 조회
    • filter는 여러건 조회
    • 쿼리셋 형태로 반환
  • >>> 모델명.objects.get(조건) : 조건을 만족하는 단일 데이터 조회
    • get은 한건만 조회 : 조건을 만족하는 데이터가 정확히 하나만 존재해야 함
    • 해당 모델의 인스턴스 형태로 반환
    • 데이터가 없거나, 조건을 만족하는 데이터가 여러 개일 경우 에러가 발생

  • >>> 변수명 = 모델명(속성1=값1, 속성2=값2, 속성3=값3, 속성4=값4) : 모델 클래스의 인스턴스를 생성
  • >>> 변수명.save() : 저장 (데이터 1건 생성)
  • >>> 변수명.id : 인스턴스의 id값 확인 (데이터가 1건 생성되면 반드시 id값 생성됨)
    • id : 모델 데이터의 유일한 값, 데이터를 생성할 때마다 1씩 증가, PK라고도 함

  • >>> 조회된변수명.속성 = 값 : 데이터 수정
  • >>> 조회된변수명.save() : 저장

  • >>> 조회된변수명.delete() : 데이터 삭제 (save() 필요 없음)

  • >>> quit() ( 또는 Ctrl+Z ) : 장고 셀 종료

조회 결과는 QuerySet 객체로 반환
⇒ 모델 클래스 안에 __str__메서드를 추가하면 조회 결과는 쿼리셋 대신 해당 모델의 객체를 나타내는 문자열로 표현
표현만 문자열로 나타날 뿐, 조회 결과는 그대로 쿼리셋 형태로 반환

def __str__(self):
	return self.속성

장고 셀 참고 사이트 : 예제로 배우는 파이썬 프로그래밍 - Django 모델 API



◉ 데이터베이스 (database)

  • 프로젝트 설정에서 데이터베이스 관련 정보를 설정하고, 모델을 통해 데이터베이스와의 CRUD(Create, Read, Update, Delete) 작업을 수행 가능

사전 작업 : 설정 파일 수정

  • [config/settings.py] 파일의 DATABASES 항목 수정
    • 오라클 DB 사용 예시
    # config/settings.py
    DATABASES = {
    	"default" : {"ENGINE" : 'django.db.backends.oracle',
      				"NAME" : 'XE', # 오라클은 특별히 바꾸지 않으면 이름이 XE로 되어있음
      				"USER" : '오라클 사용자계정', # 유저이름
      				"PASSWORD" : '비밀번호', # 비밀번호
      				"HOST" : '127.0.0.1',  # 호스트 주소
      				"PORT" : '1521' # 포트번호
    	}
    }

SQLplus 관련 작업

  • SQLplus에서 사용자 생성
    -- Cmd에서 수행 (sqlplus에서는 conn으로 접속)
    splplus sys/oracle as sysdba -- sysdba권한으로 접속
    alter session set "_ORACLE_SCRIPT" = true; -- 세션 변경
    create user 사용자이름 identified by 비밀번호; -- 사용자 생성
    grant connect, resource to 사용자이름; -- 사용자에게 권한 부여
    alter user 사용자이름 default tablespace users quota unlimited on users; -- 계정권한 문제 해결
    # 터미널에서 수행( Mac )에서 sysdba권한으로 접속하는 방법 (sqlplus실행하는 방법)
    docker exec -it --user=oracle oracle sqlplus sys/oracle as sysdba
  • SQLplus에서 생성된 테이블 확인
    -- SQL plus
    conn 사용자이름/비밀번호;
    select table_name from tabs; -- 테이블이름 조회
    desc 생성한 테이블; -- 생성한 테이블 정보 확인
  • 테이블에 데이터 추가
    insert into 테이블명(속성1, 속성2, ...) values(값1, 값2, ...);
    commit; -- 커밋해야 저장됨(필수!!)

데이터베이스 접근 방식

  1. Generic View 방식

    • Django에서 제공하는 미리 정의된 재사용 가능한 뷰 클래스를 사용하여 데이터를 처리하는 방식
    • 일반적인 CRUD(Create, Read, Update, Delete) 작업을 처리하는 데 유용
    • 예를 들어, ListView, DetailView, CreateView, UpdateView, DeleteView 등의 제네릭 뷰 클래스를 사용하여 데이터를 조회, 생성, 수정, 삭제할 수 있음
    • 간단한 설정과 클래스 상속을 통해 데이터 처리를 수행
  2. ORM (Object-Relational Mapping) 방식

    • Django의 ORM을 사용하여 데이터베이스와 상호작용하는 방식
    • 데이터베이스의 테이블과 모델 클래스를 매핑하여 데이터를 조회, 생성, 수정, 삭제하는 데 사용
    • 데이터베이스 쿼리를 Python 코드로 표현할 수 있으며, 데이터베이스에 독립적인 방식으로 데이터를 처리 가능
    • 장고의 모델 클래스와 쿼리셋(QuerySet)을 통해 다양한 데이터 조작 기능을 제공
    • 데이터베이스 연산을 추상화하여 개발자가 데이터베이스에 대한 세부적인 처리 방식을 몰라도 편리하게 작업 가능
  3. 쿼리 직접 실행 방식

    • Django의 ORM을 우회하여 직접 SQL 쿼리를 실행하는 방식
    • Django는 raw() 메서드를 통해 SQL 쿼리를 실행하고, 결과를 모델 객체가 아닌 튜플이나 딕셔너리 형태로 반환
    • 복잡한 쿼리나 특정한 성능 요구사항을 충족시키기 위해 직접 SQL을 작성해야 할 때 유용
    • ORM의 편리한 기능을 사용할 수 없으므로 주의가 필요합니다.

각 방식의 간단한 예시

# 앱명/urls.py

from django.urls import path
from . import views

## 1) Generic View 사용한 경우
from 앱명.views import 클래스명1, 클래스명2

urlpatterns = [
		path("list", 클래스명1.as_view()), # /앱명/앱명_list.html 에 연결
		path("detail/<int:pk>", 클래스명2.as_view()), # /앱명/앱명_detail.html

## 2),3) ORM방식 과 직접쿼리실행 방식
urlpatterns = [
    path("list/", views.함수명),
]
# 앱명/views.py

from django.shortcuts import render
from 앱명.models import 모델명

## 1) Generic View 사용한 경우
from django.views.generic import ListView, DetailView

class 클래스명1(ListView):   # 목록자료 : object_list로 전달
		model = 모델명
class 클래스명2(DetailView):   # 상세자료 : object로 전달
		model = 모델명

## 2) ORM 방식
def 함수명(request):
		dataList = 모델명.objects.all() # 모든 요소 가져오기
		return render(request, "앱명/템플릿파일명.html", {'html에서이름':dataList})

## 3) 직접 쿼리 실행 방식
from django.db import connection # config/settings.py 에서 지정한 디비 연결자 가져옴

def dictfetchall(cursor):
		columns = [col[0].lower() for col in cursor.description]
		return [dict(zip(columns,row)) for row in cursor.fetchall()]

def 함수명(request):
		cursor = connection.cursor() # cursor : db에 데이터 읽고 쓰기 담당
		sql = "쿼리문장(ex. select * from 테이블명 order by id desc)"
		cursor.execute(sql) # 쿼리 실행
		dataList = dictfetchall(cursor)
		return render(request, "앱명/템플릿파일명.html", {'html에서이름':dataList})


◉ 폼(form)

: 사용자로부터 입력을 받고 처리하는 데 사용
: 페이지 요청 시 전달되는 파라미터들을 쉽게 관리하기 위해 사용하는 클래스
  • 사용자 인터페이스를 통해 데이터를 수집하고 유효성 검사를 수행하는 기능을 제공
  • 장고의 폼은 폼 클래스로 정의되며, HTML 폼을 생성하고 데이터 유효성 검사, 데이터 저장 등을 처리 가능

form.py 파일 생성

  • 앱 폴더 안에 forms.py 파일 따로 생성
  • forms.ModelForm 클래스를 상속받고, Meta 클래스에 모델과 필드 정보를 지정
  • 모델 폼은 기본적으로 모델과 폼을 연결하여 데이터를 처리하므로, 직접 폼 필드를 정의할 필요가 없음
# 앱명/forms.py
from django import forms
from 앱명.models import 모델_클래스명

class 폼_클래스명(forms.ModelForm):
	class Meta:
    	model = 모델_클래스명
        fields = ['속성1','속성2',...] # 폼에서 사용할 모델 클래스의 속성명
        labels = {'속성1':'표시값1', '속성2':'표시값2',...} # 폼에서 각 속성을 표시할 문자열

views.py과 템플릿에서 폼 사용하기

# 앱명/views.py
from django.shortcuts import render
from 앱명.forms import 폼_클래스명

################## 방법1) 폼 입력과 입력된 데이터 저장 함수를 따로 ##################
def 작성함수명(request):
	return render(request, "앱명/템플릿명.html", {'form':폼_클래스명()})

def 저장함수명(request):
	form = 폼_클래스명(request.POST)
    변수명 = form.save(commit=False) # 임시저장(실제 데이터가 db에 아직 저장X)
    변수명.속성 = 값 # 폼으로 입력받지 않는 데이터는 따로 입력 (ex. 작성한 시간)
    변수명.save() # 실제로 저장
    return redirect("등록한 앱명 : url 별칭")

################## 방법2) 입력과 저장 함수를 한꺼번에 ##################
def 함수명(request):
	# POST방식 (폼에 값을 입력한 후 저장버튼을 누르면)
	if request.method == 'POST': 
    	form = 폼명(request.POST) # 폼에 입력한 데이터 가져오기
        if form.is_valid(): # form이 유효한지(form에 저장된 값이 올바르지 않으면 다시 질문 등록 화면을 렌더링)
        	변수명 = form.save(commit=False)
            변수명.속성 = 값
            변수명.save()
            return redirect("등록한 앱명 : url 별칭")
    # GET방식(인수없이 생성, 폼 페이지를 들어갈 때)
	else:  # 링크를 통한 페이지 요청은 무조건 GET방식 사용됨
    	form = 폼_클래스명() 
        return render(request, '앱명/템플릿명.html', {'form':form})
<!-- templates/앱명/템플릿명.html -->
<form method="post" action="저장 시 실행되는 페이지">
		{% csrf_token %}
		{{ form.as_p }} <!-- 함수에서 전달한 폼의 객체 -->
		<button type="submit">저장</button>
</form>
  • request.POST : 화면에서 사용자가 입력한 내용들이 담겨있음
  • {% csrf_token %} : CSRF(Cross-Site Request Forgery) 공격으로부터 보호하기 위해 사용
  • {{ form.as_p }}
    • form : views.py 에서 전달한 폼의 객체 → 폼에 정의한 속성에 해당하는 HTML코드를 자동으로 생성 ⇒ 부트스트랩 적용 불가
    • 폼 객체의 as_p 메서드 : 폼 필드들을 <p> 태그로 감싸서 텍스트 형태로 표시
    • 폼 객체의 as_table 메서드 : 폼 필드들을 <table> 태그로 감싸서 텍스트 형태로 표시
    • 폼 객체의 as_ul 메서드 : 폼 필드들을 <ul> 태그로 감싸서 텍스트 형태로 표시
  • form태그의 action = “저장 시 실행되는 페이지”
    • 지정되지 않으면 현재 페이지가 디폴트로 설정됨
    • “/앱명/저장함수명”
  • CRUD 예시 : 모델과 폼을 이용한 코드


◉ 정적파일 (static)

: 웹 애플리케이션의 정적인 파일로, CSS, JavaScript, 이미지 파일 등이 포함
  • 정적 파일들을 스태틱(Static) 디렉토리에서 관리하고 제공할 수 있는 기능을 제공

사전 작업1 : 스태틱 디렉터리 생성

  • 스타일시트(stylesheet, CSS파일)을 저장하는 공간
  • 프로젝트 디렉토리에 static 디렉토리 생성

사전 작업2 : 설정 파일 수정

  • config/settings.py 파일에서 STATICFILES_DIRS 리스트변수 추가
    # config/settings.py
    (생략)
    STATIC_URL = 'static/'
    STATICFILES_DIRS = [
    		os.path.join(BASE_DIR, 'static')
    ]
    (생략)

static 파일 사용하기

  • 스태틱 디렉터리에 스타일 파일 생성(CSS, JavaScript, Images)
  • 템플릿 파일에 스타일 적용
    {% load static %}
    <link ... href="{% static '스타일파일.확장자' %}">
    (생략)
    • {% load static %} : 템플릿 최상단에 삽입해야하는 코드
      • 해당 코드를 추가해야 템플릿에서 스태틱 파일 사용이 가능
      • 템플릿파일에 static폴더를 로드
    • static 폴더 안에 있는 js 연결 : head태그 안에 <script src="{% static 'js/파일명.js' %}"></script>
    • static 폴더 안에 있는 css 연결 : head태그 안에 <link rel='stylesheet' href="{% static 'css/파일명.css' %}">
    • static 폴더 안에 있는 img 연결 : body태그 내 원하는 곳에 <img src="{static 'img/파일명.png' %}">
profile
개발, 분석 배운 내용 정리하기!

0개의 댓글