DJANGO 정리

0302_TIL

Django

  • 파이썬 무료 오픈소스 웹 App Framework

​ == 요청 ==>

클라이언트 서버

(웹브라우저) <== 응답 == (Django)

정적 웹 페이지 ( static web page )

  • 서버에 미리 저장된 파일이 사용자에게 그대로 전달되는 웹페이지
  • 모든 상황에서 모든 사용자에게 동일한 정보를 표시
  • 일반적으로 HTML,CSS,JavaScript
  • flat 페이지라고도 함
  • 추가적인 처리과정이 없음

동적 웹 페이지 ( Dymamic web page )

  • 추가적인 처리과정 이후 클라이언트에게 응답을 보냄
  • 방문자와 상호작용 하기 때문에 페이지 내용은 그때그때 다름
  • 서버 사이드 언어(Python, Java, C++)가 사용되며, 데이터베이스와의 상호작용이 이루어짐

Framework

  • 웹 서비스를 만드는 데 필요한 도구들

  • 프로그래밍에서 특정 운영 체제를 위한 응용 프로그램 표준 구조를 구현하는 클래스와 라이브러리 모임

  • 재사용 할 수 있느 수많은 코드를 프레임워크로 통합함으로써, 개발자가 새로운 애플리케이션을 위한 표준 코드를 다시 작성하지 않아도 같이 사용할 수 있도록 도음

  • Application framework 라고도 함

Web framwork

  • 웹 페이지를 개발하는 과정에서 어려움을 줄이는 것이 목적

    데이터베이스 연동, 템플릿 형태의 표준, 세션 관리 , 코드 재사용등의 기능을 포함

  • 동적 웹 페이지나, 웹 어플리케이션 , 웹 서비스 개발 보조용

Django를 사용하는 이유

  • 검증된 Python 언어 기반의 Web Framwork

TIps

manage.py 가 있는 위치 -> project root

Django 생성

  1. 파이썬 가상환경 만들기 (python -m venv venv)
  2. 가상환경 실행 ( source venv/Scripts/activate )
  3. 장고 설치 ( pip install djagno==3.2.10)
  4. 프로젝트설치 ( django-admin startproject <이름> .)
  5. Application 만들기 ( python manage.py startapp articles )
    • Application 명은 복수형으로 하는 것을 권장
    • Application 등록후, 프로젝트파일안 settings.py에 등록 해야함
  6. templates 는 articles(Application) 안에 폴더 생성 후, html 파일 생성

Views.py (application)

def index(request):
    # request 반드시 써줘야함
    return render(request,'index.html')
	# request 반드시 써줘야함

urls.py (project)

from articles import views 			# Application 에 views를 import 해줘야함

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index), 	# 파일의 주소,  끝난 뒤 , 꼭 찍어둘것
]

순서는 항상 URL -> VIEW => TEMPLATE

TIPS

from django.http import HttpResponse

def welcome(request):
    return HttpResponse('<h1> Hola ! <h1>')

>> Hola! 출력

Django Template Language ( DTL )

  • Django Template에서 사용하는 built-in template system

  • 조건, 반복, 변수 , 치환 , 필터 등의 기능을 제공

  • 단순이 Python 이 Html 에 포함 된 것이 아니며,

    프로그래밍 로직이 아닌 프레젠테이션을 표현하기 위한것

  • if , for 문 등이 사용 되긴 하지만 Python 코드로 실행되는 것이 아님

DTL Syntax

{{ variable }}

  • rander() 를 사용하여, views.py 에서 정의한 변수를 template파일로 넘겨 사용하는 것

  • 변수 명은 영어, 밑줄을 포함 가능, 단 밑줄 시작은 안됨

  • dot(.) 을 사용하여 변수 속성에 접근 가능

  • render() 의 세번째 인자로 {'key' : value} 와 같이 딕셔너리 형태로 넘겨주며,

    여기서 정의한 key에 해당하는 문자열이 template에서 사용 가능한 변수명이 됨

def greeting(request):
    return render(request,'greeting.html',{'name' : 'Alice',})
	# render 함수의 세번째 인자 값을 딕셔너리 형태로 저장 해야한다.
/* HTML 에서 DTL 변수를 사용하기 위해선 {{ 변수명 }} 와 같이 사용 */
<p>안녕하세요 저는 {{name}}입니다.</p>
  • 변수가 많아진다면?
def greeting(request):
    # 관용적으론 변수는 context 라는 이름으로 사용
    context=dict(name='Alice')
    return render(request,'greeting.html',context)
def greeting(request):
    foods = ['apple','banana','cocount',]
    info={
        'name':'Alice',
    }
    context={
        'foods' : foods,
        'info' : info,
    }
    return render(request,'greeting.html',context) # context 접근시 딕서녀리의 왼쪽 키 값을 통해 접근한다.
  <p>안녕하세요 저는 {{info.name}}입니다.</p>
>>안녕하세요 저는 Alice입니다.		# dot(.) 을 통해 접근
  <p>제가 가장 좋아하는 음식은 {{ foods }} 입니다.</p>
>>제가 가장 좋아하는 음식은 ['apple', 'banana', 'cocount'] 입니다.
  <p>저는 사실 {{ foods.0 }} 입니다.</p> # dot(.) 을 찍으면 인덱스 접근이 가능하다.
>>저는 사실 apple 입니다.

Filters

{{variable | filter }}

  • 표시할 변수를 수정할 때 사용

ex)

  • name 변수를 모두 소문자로 출력

    • {{name | lower}}
    <p>안녕하세요 저는 {{info.name|lower}}입니다.</p>
    >> 안녕하세요 저는 alice입니다.
  • filter 는 chain 이 가능하다

def dinner(request):
    foods = ['족발','햄버거','치킨','초밥']
    pick = random.choice(foods)
    context = {
        'pick' : pick,
        'foods' : foods,
    }
    return render(request,'dinner.html',context)
 <p>오늘의 추천 음식은 {{pick}} 입니다!</p>
  <p>{{pick}} 은 {{pick|length}} 글자 입니다</p>
  <p>{{ foods|join:', '}}</p>
>> 족발,햄버거,치킨,초밥
  <a href="/index/"> 뒤로 </a>

Tags

  • 출력 텍스트를 만들거나 , 반복 또는 논리를 수행 하여 제어 흐름을 만드는등 변수보다 복잡한 일 들을 수행

  • 일 부태그는 시작과 종료태그가 필요

    • {% if %}{% end if %}
    <p> 메뉴판 </p>
      <ul>
        {% for food in foods  %}
          <li>{{food}}</li>
        {% endfor %}
      </ul>
    메뉴판
    
    족발
    햄버거
    치킨
    초밥
  • 약 24개

{# 이것은 한 줄 주석 입니다.#}


Django 상속

  • 하나의 base.html 을 만들고 이를 상속받아서 사용할수 있는 자식 template를 사용

    • 코드의 재사용성

    • 모든 공통 요소를 포함하고, 하위 템플릿이 재정의 할 수 있는 블록을 정의하는

      기본 "skeleton" 템플릿을 만들 수 있음

  • 장고에게 추가 템플릿 경로 등록한다고 말해줘야한다. (우리만의 별도의 경로)

    • settings.py => TEMPLATES => DIR 에다 등록

    • # base.html 이 포함된 templates 폴더를 최상단에다가 생성 뒤 settings에 작성
      'DIRS': [BASE_DIR / 'templates',],

Template inheritance - "tags"

{% extends ' 부모.html' %}

  • 자식 템플릿이 부모 템플릿을 확장 한다는 것을 알림
  • 반드시 템플릿 최상단에 작성 되어야함

{% block content %} { % endblock % }

  • 하위 템플릿에서 재지정(overridden) 할 수 있는 블록을 정의
  • 즉 , 하위 템플릿이 채울 수 있는 공간

0303_TIL

from django.shourtcuts import render

=> 화면을 렌더링 해서 사용한다.

#views.py
def index(request):
    context = dict()			# 딕셔너리 형태로 key 값이 템플릿의 변수명
    return render(request,'A.html',context) # render 함수의 인자들

HTML Form

  • 사용자에게 정보를 입력 받기 위해 사용

  • 핵심 속성(attribute)

    • action : 입력 데이터가 전송될 URL 지정 (데이터 어디로 보낼건데?)
    • method : 입력 데이터 전달 방식 지정 ( GET 방식 , POST 방식 )
      • GET , POST 차이 ( 보안성 )
      • GET -> 데이터를 달라고 할 때 (보안성 떨어짐)
      • POST -> 게시글 작성, 회원가입 등등을 수행 하고자 할 때 사용

'input' element

  • type 속성에 따라 동작 방식이 달라짐

  • 핵심 속성(attribute)

    • name : 데이터의 이름을 지정

    • 주요 용도는 GET/POST 방식으로 서버에 전달하는

      파라미터 (name 은 key, value 는 value) 로 매핑 하는 것

    • GET 방식에서는 URL ?key=value&key=value 형식으로 데이터를 전달함

      • GET 방식은 URL에 데이터를 담아서 넘겨준다.(쿼리스트링)
      • POST 요청 => body 영역에 데이터를 한겹 숨겨서 데이터를 정송

'label' element

  • 사용자 인턴페이스 항목에 대한 설명
  • label을 input 요소와 연결하기
    • input 에 id 속성 부여
    • label 에는 input의 id와 동일한 값의 for 속성이 필요
  • label 과 input 요소 연결의 이점
    • label을 클릭해서 input에 초점(focus)를 맞추거나 활성화(activate) 시킬 수 있음

'for' attribute

  • for 속성의 값과 일치하는 id를 가진 문서의 첫번째 요소를 제어
  • "labelable element"
    • label 요소와 연결 가능
    • button , input , select

'id' attribute

  • 문서에서 고유 해야하는 식별자를 정의

HTTP

  • 모든 데이터 교환의 기초
  • 주어진 리소스가 수행해야 할 작업을 나타내는 request methods를 정의
  • HTTP request method 종류
    • GET , POST , PUT , DELETE ... 등등

GET

  • 서버로 부터 정보를 조회하는데 사용
  • 데이터를 가져올 때만 사용해야 함
  • 데이터를 서버에 정속할 때 쿼리스트링을 통해 전송 ( ?key&value)
  • 서버에 요청 시, HTML 문서 파일 한장을 받는다. => GET 요청 방식
def throw(request):
    return render(request,'throw.html')

def catch(request):
    message = request.GET.get('message')       # request 안에 있는 GET 방식에서 get('message') message로 된 이름의 것을 받아와
    context = dict(
        message = message,
    )
    return render(request,'catch.html',context)
# Throw
<form action="/catch/">
  <label for="message">메시지</label>
  <input type="text" id='message' name='message'>
  <input type="submit">
</form>

# catch
{% extends 'base.html' %}
{% block content %}
<h1>Catch</h1>
<h2>{{message}}</h2>
<a href="/throw/"> throw 로 가자</a>
{% endblock content %}

URL

Variable Routing

  • URL 주소를 변수로 사용하는 것

  • URL 의 일부를 변수로 지정하여 view 함수의 인자로 넘길 수 있음

  • 즉, 변수 값에 따라 하나의 path() 에 여러 페이지를 연결 시킬 수 있음

    • path ('accounts/user/<<int:user_pk>>/',...)

      • account/user/1 -> (1번 user 관련 페이지 )
      • account/user/2 -> (2번 user 관련 페이지 )

URL Path converters

path ('hello/<<str:name>>',views.hello)

  • str
    • '/'를 제외하고 비어 있지 않은 모든 문자열과 매치
    • 작성하지 않을 경우 기본 값
  • int
    • 0 또는 양의 정수와 매치
  • slug
# urls.py
path('hello/<str:name>/',views.hello),          # hello 다음 매칭 되는게 문자열일 때 , name이라는 변수 받아서 hello view 로 넘겨
path('intro/<str:name>/<int:age>/',views.intro),

# vies.py
def hello ( request, name):
    context = dict(
        name = name,
    )
    return render(request,'hello.html',context)


def intro (request,name,age):
    context = dict(
        name = name,
        age = age,
    )
    return render(request,'intro.html',context)
{% extends 'base.html' %}
{% block content %}
<h1>Hello ! {{name}} </h1>
{% endblock content %}

{% extends 'base.html' %}
{% block content %}
<h1>안녕하세요 {{name}} 님 {{age}}살 입니다.</h1>
{% endblock content %}

App URL mapping

  • app 의 view 함수가 많아지면서 사용하는 path() 또한 많아지고,

    app 또한 더 많이 작성하기 때문에, url.py 에서 모두 관리하는 것은 유지보수에 좋지 않다.

  • 각 app 에 urls.py를 작성하게 됨

## urls.py firstpjt
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('articles/', include('articles.urls')),
    path('pages/',include('pages.urls')),
]

####################################################

## urls.py articles

from django.urls import path
from . import views

urlpatterns = [
    path('index/', views.index),
    path('greeting/',views.greeting),
    path('dinner/', views.dinner),
    path('hi/',views.hi),
    path('throw/',views.throw),
    path('catch/',views.catch),
    path('hello/<str:name>/',views.hello),          # hello 다음 매칭 되는게 문자열일 때 , name이라는 변수 받아서 hello view 로 넘겨
    path('intro/<str:name>/<int:age>/',views.intro),
]
###################################################

## urls.py pages

from django.urls import path
from . import views

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

## views.py pages
from django.shortcuts import render

# Create your views here.
def index(request):
    return render(request,'pages/index.html')
	# render 안 경로도 app/A.html 형식으로 바꿔줘야 한다.

Naming URL patterns

  • 이제는 링크에 url을 직접 작성하는 것이 아니라 path() 함수의 name 인자를 정의해서 사용
  • Django Template Tag 중 하나인 url 태그 사용해서 path() 함수에 작성한 name을 사용할수 있음
  • url 설정에 정의된 특정한 경로들의 의존성을 제거할 수 있음
from django.urls import path
from . import views

urlpatterns = [
    path('index/', views.index , name='index'),
    path('greeting/',views.greeting , name = 'greeting'),
    path('dinner/', views.dinner ,name = 'dinner'),
    path('hi/',views.hi , name = 'hi'),
    path('throw/',views.throw  ,name = 'throw'),
    path('catch/',views.catch ,name = 'catch'),
    path('hello/<str:name>/',views.hello ,name = 'hello'),          # hello 다음 매칭 되는게 문자열일 때 , name이라는 변수 받아서 hello view 로 넘겨
    path('intro/<str:name>/<int:age>/',views.intro , name = 'intro'),
]

#####################################################

{% extends 'base.html' %}
{% block content %}
<h1>Throw</h1>

			 #{% url 'name' %}
<form action="{% url 'catch'%}">
  <label for="message">메시지</label>
  <input type="text" id='message' name='message'>
  <input type="submit">
</form>

{% endblock content %}

각자 다른 앱에 name이 중복 된 경우

from django.urls import path
from . import views
# app_name 을 작성
app_name = 'pages'
urlpatterns = [
    path('index/', views.index,name='index'),
]


###
# app_name : name 형식으로 url 작성
<a href={% url 'pages:index' %}> 두번째 인덱스 </a>

03_04 TIL

Django Namespace

  • 이름이 중복된 경우

  • 하나의 이름 공간에서는 하나의 이름이 단 하나의 객체만을 가리키게 된다

  • Django 에서는

    • 서로 다른 app의 같은 이름을 가진 url name은 이름 공간을 설정해서 구분
    • templates, static 등 django는 정해진 경로 하나로 모아서 보기 때문에 중간에 폴더를 임의로 만들어 줌으로써 이름공간을 설정한다.
      • 어떤 앱의 url 인가?
    #urls#
    app_name ='pages'		# app_name 설정
    urlpatterns = [
        path('index/',views.index),
    ]
    #html#
    <a href="{%url 'pages : index'%}"> 두번째 앱 메인 페이지로</a>

    templates 안에 앱 이름과 똑같은 폴더를 만들어 준 뒤

    html 파일을 그 안에 넣어준다

    templates\articles

Static File 구성

  • jango.contrib.staticfiles 가 Installed_APPS 에 있는지 확인

  • settings.py 에서 STATIC_URL 을 정의

  • static 템플릿 태그를 사용하여 지정된 상대경로에 대한 URL을 빌드

{% load static %}
<img src="{% static 'my_app/example.jpg' %}" alt ="my mage" >
  • 앱의 static 디렉토리에 정적 파일을 저장

    app / static / app 과 같이 경로를 설정

The staticfiles app

  • STATICFILES_DIRS

    • ' app / static / '디렉토리 경로(기본 경로) 를 사용하는 것 외에

      추가적인 정적 파일 경로 목록을 정의하는 리스트

    • 추가 파일 디렉토리에 대한 전체 경로를 포함하는 문자열 목록으로 작성되어야 함

  • STATIC_URL

    • STATIC_ROOT 에 있는 정적 파일을 참조 할 때 사용할 URL

      • 개발 단계에서는 실제 정적 파일들이 저장되어 있는 'app / static /' 경로 및

      STATICFILES_DIRS 에 정의된 추가 경로들을 탐색함

    • 비어있지 않은 값으로 설정한다면 반드시 / 로 끝나야함

    • 실제 파일이나 디렉토리가 아니며 URL 로만 존재

  • STATIC_ROOT

    • 배포를 위해 정적 파일을 수집하는 디렉토리의 전체 경로

    • 모든 정적 파일을 한 곳에 모아 넣는 경로

    • 개발 과정에서 settings.py 의 DEBUG 값이 True 로 설정시 작용 도지ㅣ 않음

      • 직접 작성하지 않으면 django 프로젝트 에서는 settings.py 에 작성되어 있지 않음
    • 실 서비스 환경(배포 환경) 에서 django의 모든 정적파잉릉ㄹ 다른 웹 서버가 직접 제공하기 위함

    • STATIC_ROOT = BASE_DIR / 'staticfiles'

      python manage.py collectstatic

      => 배포 준비

Django template tag

  • load

    • 사용자 정의 템플릿 태그 세트를 로드
    • 로드하는 라이브러리, 패키지에 등록된 모든 태그와 필터를 불러옴
  • static

    • STATIC_ROOT 에 저장된 정적 파일에 연결

    • {% load static %}
      <img src="{% static 'my_app/example.jpg' %}" alt ="my mage" >

      경로 -> pages 폴더 안 static 폴더 생성 후, 앱 이름

    • {% extends 'base.html' %} <!--항상 최상단에 위치 해야함-->
      {% load static %} <!-- extends 아래 load-->
      {% block content %}
        <img src="{% static 'sample.jpg' %}" alt="sample image" style = 'width:300px'>
        <h1> 두번째 앱은 INDEX 페이지 </h1>
      {% endblock content %}
    • settings.py 안

      STATICFILES_DIRS = [
          BASE_DIR/'static',
      ]

      작성 후, 최 상단에 static 폴더 생성 -> 폴더 안 css 파일 생성

      base.html head 부분 block style 생성

      style 적용 원하는 html 에 다음과 같이 작성

      {% block style %}
        <link rel="stylesheet" href="{% static 'style.css'%}">
      {% endblock style %}

0308_TIL

TIPS


pip freeze > tab

=>requirements.txt 에 자동 저장

장고 INSTALLED_APPS

내가 설치한 앱

내가 설치한 패키기

장고가 추가한것

http method

get

  • 기본값 , 서버 리소스 요청할때, URL 전송

post

  • 리소스 생성 , 수정, 삭제
  • CUD
  • BODY
  • {% csrf_token %}
    • post 방식에서 사용

Model

  • 단일한 데이터에 대한 정보를 가진다
    • 사용자가 저장하는 데이터들의 필수적인 필드들과 동작들을 포함
  • 저장된 데이터베이스의 구조 ( layout )
  • Django 는 model을 통해서 데이터에 접근/ 관리
  • 일반적으로 model은 하나의 데이터 베이스 테이블에 매핑

Database

  • DB
    • 체계화된 데이터의 모임
  • 쿼리(Query)
    • 데이터를 조회하기 위한 명령어
    • 조건에 맞는 데이터를 추출하거나 조작하는 명령어
    • "Query를 날린다." => DB를 조작한다.

Database 의 기본 구조

  • 스키마(Schema)
    • 데이터베이스에서 자료의 구조, 표현방법, 관계등을 정의한 구조(structure) => 설계도
  • 테이블(Table)
    • 열(column) : 필드(field) or 속성
    • 행(row) : 레코드(record) or 튜플 ( 테이블의 데이터는 행에 저장 된다.)
  • PK(기본키) : Primary Key : 각각의 데이터를 구분 할 수 있는 고유 값

ORM

  • Object - Relational - Mapping : 객체 관계 매핑 ( 데이터베이스를 모델 객체접근을 하겠다.)

  • 객체 지향 프로그래밍 언어를 사용하여 호환되지 않는 유형의 시스템 간의 ( Django - SQL )

    데이터를 변환하는 프로그래밍 기술

  • OOP 프로그래밍에서 RDBMS을 연동할 때 호환되지 않는 데이터를 변환하는 프로그래밍 기법

  • Django 는 내장 Django ORM을 사용한다.

ORM의 장점과 단점

  • 장점
    • SQL을 잘 알지 못해도 DB 조작이 가능
    • 객체 지향적 접근으로 인한 높은 생산성
  • 단점
    • ORM만으로 완전한 서비스를 구현하기 어려운 경우가 있음
    • 효율성이 떨어진다
  • 현대 웹 프레임워크의 요점은 웹 개발의 속도를 높이는 것 ( 생산성 )

Models.py

  • 데이터의 구조를 적는다
  • app 별로 나눠서 적을 수도 있음
  • class 형식으로 적는다.
from django.db import models

# Create your models here.
class Article(models.Model):
    # CharField() => 제목 ( max_length 를 지정 )
    title = models.CharField(max_length=30)
    # TextField() => 텍스트 내용 (제한 없음)
    content = models.TextField()
    # DataTimeField() => 현재시간
    # auto_now_add => 최초의 데이터가 생성 될 때, 최초의 시간을 저장
    created_at = models.DateTimeField(auto_now_add=True)
    # auto_now => 데이터가 수정이 될 때마다 시간을 저장
    updated_at = models.DateTimeField(auto_now = True)


    def __str__(self):
        return self.title
  • model 조작 (생성 , 수정 ,삭제) 시에

    • migration 생성 ( model 의 history (like git))

      # 2
      python manage.py makemigrations
    • migration을 반영 해줘야 한다. (적용)

      # 3
      python manage.py migrate

Field options

  • null => DB에 null 값을 저장

  • none => 아무 값도 저장 하지 않음

    ORM이 변환한 언어를 볼 수 있음 python -> SQL

# python manage.py sqlmigrate <앱 이름> < migrations 번호>
python manage.py sqlmigrate articles 0001

어떤 migration이 있고, 어떤 것이 적용 되어 있는지 확인하는 명령어

python manage.py showmigrations

ORM을 연습 할 수 있는 곳

python manage.py shell
  • ORM은 모델객체를 이용하기 때문에 먼저 앱의 모델을 가져와야함
# 데이터 추가하는 case 1
# 인스턴스 생성 후 save

>>> from articles.models import Article 
>>> Article.objects.all()
<QuerySet []>
>>> article = Article() => Article() 인스턴스 생성
>>> article.title = "첫번째 글"  
>>> article.content = "푸틴이 정신을 차려야 할텐데..."
>>> Article.objects.all()
<QuerySet []>
>>> article.save()
>>> Article.objects.all()
<QuerySet [<Article: Article object (1)>]>
>>> article = Article.objects.all()[0]
>>> article
<Article: Article object (1)>
>>> article.title
'첫번째 글'
>>> article.content
'푸틴이 정신을 차려야 할텐데...'
# 데이터 추가 case 2
# 키워드 인자를 넘기는 방식

>>> article = Article(title = "두번째 글", content = "점심때는 좀 자야 돼 진짜 ")  
>>> article.save()
>>> Article.objects.all()
<QuerySet [<Article: Article object (1)>, <Article: Article object (2)>]>
>>> article = Article.objects.all()[1]
>>> article.title
'두번째 글'
>>> article.content
'점심때는 좀 자야돼 진짜 '
# 데이터 추가 case 3 => save가 필요 없음
# Article.objects.crate()

>>> Article.objects.create(title = "세번째 글" , content ="다이어트는 내일부터")  
<Article: Article object (3)>
>>> Article.objects.all()
<QuerySet [<Article: Article object (1)>, <Article: Article object (2)>, <Article: Article object (3)>]>

Shell 은 조금 더 가독성 있게 사용.

pip install django-extensions

-> settings.py에 등록하자

  • QuerySet => DB에 저장된 객체의 목록

extensions 에서 all / get / filter 사용

In [4]: article1=Article.objects.all()[0]

In [5]: print(article1)
첫번째 글

									# 조건으로 id 값을 불러와줘야해
In [8]: article = Article.objects.get(id=1)
     #	article = Article.objects.get(pk=4) pk라고 써도 돼							

In [9]: article.title
Out[9]: '첫번째 글'
    

    # filter 조건과 일치하는 모든것들을 가져온다
In [22]: articles = Article.objects.filter(title='첫번째 글')
In [23]: articles
Out[23]: <QuerySet [<Article: 첫번째 글>, <Article: 첫번째 글>]>

Field lookups

  • get 과 filter 사용시 사용되는 조건들을 명시 해준다.

​ -> https://docs.djangoproject.com/en/3.2/ref/models/querysets/#field-lookups

에서 찾자

In [28]: aricles = Article.objects.filter(title__contains='첫')

In [29]: aricles
Out[29]: <QuerySet [<Article: 첫번째 글>, <Article: 첫번째 글>]>

Update

In [36]: article.title = "네번째 글"

In [37]: article.save()

In [38]: article
Out[38]: <Article: 네번째 글>

In [39]: Article.objects.all()
Out[39]: <QuerySet [<Article: 첫번째 글>, <Article: 두번째 글>, <Article: 세번째 글>, <Article: 네번째 글>]>

Delete

In [40]: article.delete()
Out[40]: (1, {'articles.Article': 1})

In [41]: Article.objects.all()
Out[41]: <QuerySet [<Article: 첫번째 글>, <Article: 두번째 글>, <Article: 세번째 글>]>

관리자 기능

$ python manage.py createsuperuser
Username (leave blank to use 'my'): jongram 
Email address: [email protected]
Password: 
Password (again):

admin.py 에 등록

from django.contrib import admin
from .models import Article

# Register your models here.
admin.site.register(Article)

models 활용하기

views.py

from .models import Article
# Create your views here.
def index(request):
    # 1. 모델을 이용해서 모든 데이터를 가져온다.
    # 2. 가져온 데이터를 템플릿으로 넘기다.
    # 3. 템플릿에서 데이터를 보여준다.
    articles = Article.objects.all()
    # 다음과 슬라이싱 하면 뒤에서 부터 출력 가능 하다.
    #articles = Article.objects.all()[::-1]
    
    # DB에서 가져올떄 부터 정렬을 시킬 수 있음
    # articles = Article.objects.order_by('pk')
    # 내림차순 정렬
    # articles = Article.objects.order_by('-pk')
    
    context = dict(
        articles = articles,
    )
    return render(request,'articles/index.html',context)
{%comment%} index.html {%endcomment%}
{% extends 'base.html' %}
{% block content %}

{% for article in articles %}
<h3># {{article.id}}</h3>
<h5>제목 : {{article.title}}</h5>
<article>{{article.content}}</article>
<hr>
{% endfor %}

{% endblock content %}

글쓰기


Views.py

def new(request):
    return render(request,'articles/new.html')

def create(request):
    # new에서 넘어온 데이터를 get 방식을 통해 받아온 뒤 저장
    title = request.GET.get('title')
    content = request.GET.get('content')
    # 데이터베이스에 저장 해주는 함수
    Article.objects.create(title=title, content=content)
    return render(request,'articles/create.html')

new.html

{% extends 'base.html' %}
{% block content %}
<h1 class="text-center">new article</h1>
{%comment%} action으로 create.html에 데이터 전송(get방식){%endcomment%}
<form action={% url 'articles:create' %}>
  <label for="title" class="my-3">Title : </label>
  <input type="text" id="title" name="title">
  <br>
  <label for="content">Content : </label><br>
    {%comment%} textarea 로 깔끔하게 작성 {%endcomment%}
  <textarea name="content" id="content" cols="30" rows="5"></textarea><br>
  <input type="submit">
</form>
<br>
<a href= {% url 'articles:index' %}>목록보기</a>
{% endblock content %}

create.html

{% extends 'base.html' %}
{% block content %}
<h1 class="text-center">작성완료</h1>
{% endblock content %}

POST 방식으로 변환

new.html

{% extends 'base.html' %}
{% block content %}
<h1 class="text-center">new article</h1>
<form action={% url 'articles:create' %} method ="POST">
  {%comment%} post방식 쓸때는 무조건 csrf_token {%endcomment%}
  {% csrf_token %}
  <label for="title" class="my-3">Title : </label>
  <input type="text" id="title" name="title">
  <br>
  <label for="content">Content : </label><br>
  <textarea name="content" id="content" cols="30" rows="5"></textarea><br>
  <input type="submit">
</form>
<br>
<a href= {% url 'articles:index' %}>목록보기</a>
{% endblock content %}

views.py

def create(request):
    title = request.POST.get('title')
    content = request.POST.get('content')
    Article.objects.create(title=title, content=content)
    return render(request,'articles/create.html')

create 말고 글쓰기 완료 후 index로 이동

									# 사용자를 특정 url로 보내버림
from django.shortcuts import render , redirect

def create(request):
    title = request.POST.get('title')
    content = request.POST.get('content')
    Article.objects.create(title=title, content=content)
    	# redirect(url) 방식으로 써주자
    return redirect('articles:index')

SQL

0314_TIL

데이터베이스(DB)

  • 체계화된 데이터의 모임

  • 여러사람이 공유하고 사용할 목적으로 통합 관리된느 정보의 집합

  • 논리적으로 연관된 (하나 이상의) 자료의 모음

    내용을 고도록 구조화 하면서 검색과 갱신의 효율화

  • 몇 개의 자료 파일을 조직적으로 통합하여

    자료의 중복을 없애고 자료를 구조화하여 기억시켜놓은 자료의 집합체

장점

  • 중복 최소화 , 무결성(정확한 정보) , 데이터 일관성, 데이터 독립성, 데이터 표준화 , 데이터 보안 유지

관계형 데이터베이스(RDB)

  • Relational Database
  • 키와 값들의 간단한 ㅗ간계를 표 형태로 정리한 데이터 베이스
  • 관계형 모델에 기반
  • 용어
    • 스키마 : 데이터 베이스에서 자료의 구조, 표현 방법, 관계 등 전반적인 명세를 기술한 것
    • 테이블 : 열 과 행 의 모델을 사용해 조직된 데이터 요소들의 집합
    • 열 (column) : 각 열에는 고유한 데이터 형식이 지정됨
    • 행 (row) : 실제 데이터가 저장되는 형태
    • 기본키 (PK) : 각 행(레코드)의 고유 값 , 반드시 설정 해줘야 한다.

SQLite

  • 서버 형태가 아닌 파일 형식으로 응용 프로그램에 넣어서 사용하는 비교적 가벼운 데이터베이스
  • 구글 안드로이드 운영체제에서 기본적으로 탑재된 데이터 베이스

Sqlite Data Type

  1. NULL
  2. INTEGER
    • 크기에 따라 0,1,2,3,4,6 또는 8바이트에 저장된 부호 있는 정수
  3. REAL
    • 부동 소수점 , 실수
  4. TEXT
  5. BLOB
    • 타입 없이 그대로 저장

Sqlite Type Affnity

  • INTEGER
  • TEXT
  • BLOB
  • REAL
  • NUMERIC

SQL ( Structured Query Language )

  • 관계형 데이터베이스 관리 시스템의 데이터 관리를 위해 설계된 특수 목적으로 프로그래밍 언어
  • 데이터베이스 스키마 생성 및 수정
  • 데이터베이스 객체 접근 조정 관리

SQL분류

  • DDL - 데이터 정의 언어 ( CREATE , DROP , ALTER ) : 테이블, 스키마등 등을 정의
  • DML - 데이터 조작 언어 ( INSERT , SELECT , UPDATE, DELETE ) : 데이터를 저장 조회 등등
  • DCL - 제이터 제어 언어 (GRANT,REVOKE)

Table 생성 (CREATE)

CREATE TABLE classmates (
  id INTEGER PRIMARY KEY,
  name TEXT
);

삭제 (DROP)

DROP TABLE classmates;

삽입(INSERT)

INSERT INTO classmates ( name, age ) VALUES ('홍길동',23)
INSERT INTO classmates VALUES('홍길동',30,'서울');

rowid 출력

SELECT rowid, * FROM classmates;

NULL

  • NOT NULL 을 설정해주어서 데이터를 꼭 들어갈수 있도록 해줘야 한다.
CREATE TABLE classmates (
    -- primary key 값은 integer 로 해줘야 해!
    -- 스키마에 id를 직접 작성 했기 때문에, 입력할 column 을 명시하지 않으면 실행 되지 않는다.
  id INTEGER  PRIMARY KEY,
  name TEXT not null,
  age INT not null,
  address TEXT not null
);

여러 데이터 한번에 INSERT

INSERT INTO classmates VALUES
('홍길동',30,'서울'),
('김철수',30,'대전'),
('이싸피',26,'광주'),
('박삼성',29,'구미'),
('최전자',28,'부산');

READ ( 조회 )

  • 가장 중요

  • SELECT 문

    • 테이블에서 데이터를 조회
    • SQLite 에서 가장 복잡한 문이며 다양한 절 과 함께 사용
      • ORDER BY , DISTINCT , WHERE , LIMIT , GROUP BY ...
    • LIMIT
      • 쿼리에서 반환되는 행 수를 제한
      • 특정 행 부터 시작해서 조회하기 위한 OFFSET 키워드와 함께 사용 하기도 함
    • WHERE
      • 쿼리에서 반환된 행에 대한 특정 검색 조건을 지정
    • SELECT DISTINCT
      • 조회 결과에서 중복 행을 제거
      • DISTINCT 절은 SELECT 키워드 바로 뒤에 작성 해야 한다.
-- 전체 출력
SELECT rowid,name from classmates;

-- 1명만 출력되도록 제한
select rowid,name from classmates limit 1;

-- offset 사용시 0 부터 시작한다고 생각하자.
SELECT rowid,name from classmates limit 1 offset 2;

-- 주소가 서울인 경우
SELECT rowid,name from classmates where address = '서울';

-- age 값 전체 출력
SELECT DISTINCT age FROM classmates;

AUROINCREMENT

  • SQLite 가 사용되지 않은 값이나 이전에 삭제된 행의 값을 재사용 하는 것을 방지한다.
  • 테이블 생성 단계에서 AUROINCREMENT 를 통해 설정이 가능하다.

.csv import 하기

sqlite> .mode csv
sqlite> .import users.csv users

Aggregate funcction

  • "집계 합수"

  • 값 집합에 대한 계산을 수행하고 단일 값을 반환

  • SELECT 구문에서만 사용됨

  • 예시

    • 전채 행수 구하는 COUNT(*)
    • age 컬럼 전체 평균 값을 구하는 AVG(age)
      • MAX ,MIN , SUM 등등
select count(*) from users;

select avg(age) from users where age>=30;

select first_name,max(balance) from users;

select avg(balance) from users
where age>= 30;

LIKE operator

  • 패턴 일치를 기반으로 데이터를 조회하는 아법
  • SQLite 는 패턴 구성을 위한 2개의 wildcards를 제공
    • % (percent sign ) : 이 자리에 문자열이 있을수도 , 없을수도 있다.
    • _( underscore ) : 반드시 이 자리에 한개의 문자가 존재해야한다
  • wildcard 사용시
    • 2% : 2로 시작하는 값
    • %2 : 2로 끝나는 값
    • %2% : 2가 들어간느 값
    • _2% : 아무 값이 하나 있고 두번쨰가 2로 시작하는 값
    • 1____ : 1로 시작하고 총 4자리 인값
    • 2 % % / 2 __ % : 2로 시작하고 적어도 3자리인 값
select * from users
where age like'2_';


select * from users
where phone like '02-%';


select * from users
where first_name like '%준';

select * from users
where phone like '%-5114-%';

ORDER BY 절

  • ORDER BY

    • 조회 결과 집합을 정렬
    • SELECT 문에 추가하여 사용
    • 정렬 순서를 위한 2개의 keyword 제공
      • ASC - 오름차순 ( default )
      • DESC - 내림차순
  • -- ORDER BY 기본값 -> ASC
    select * from users ORDER BY age DESC LIMIT 10;
    select * from users ORDER BY age,last_name LIMIT 10;
    
    select last_name , first_name from users
    ORDER BY balance LIMIT 10;

GROUP BY

  • GROUP BY
    • 행 집합에서 요약 행 집합을 만듦
    • SELECT 문의 optional 절
    • 선택된 행 그룹을 하나 이상의 열 값으로 요약 행으로 만듦
    • 문장에 WHERE 절이 포함된 경우 반드시 WHERE 절 뒤에 작성해야 함

Q. users 에서 각 성 씨가 몇명씩 있는지 조회

select last_name , count(*) from users GROUP BY last_name;
  • AS 를 활용하여 count 에 해당하는 컬럼명을 바꿔서 조회 할 수 있음

    select last_name , count(*) AS name_count from users GROUP BY last_name;

ALTER TABLE

  • ALTER TABLE 의 3가지 기능

    • table 이름 변경

    • 테이블에 새로운 column 추가

    • column 이름 수정

      ALTER TABLE table_name
      RENAME COLUMN current_name TO new_name;
    • 테이블 이름 변경

      ALTER TABLE article RENAME TO new_article;
    -- 새로운 컬럼 추가
    -- 기존 컬럼이 있을 경우 NOT NULL 을 하게 되면 ERROR 발생
    ALTER TABLE news  add COLUMN created_at TEXT NOT NULL;
    
    
    -- 1. NOT NULL 설정 없이 추가하기
    ALTER TABLE news 
    ADD COLUMN created_at TEXT;
    
    -- datetime('now') : 현재 시간을 기준으로 저장
    INSERT INTO news VALUES('제목','내용',datetime('now'));
    
    -- NOT NULL 을 유지 하면서 컬럼을 추가할 경우, DEFAULT 값을 설정해주면 된다.
    ALTER TABLE news
    ADD COLUMN subtilte TEXT NOT NULL
    DEFAULT '소제목';
    
    -- column 이름 변경 하기
    ALTER TABLE news
    RENAME COLUMN title to main_title;
    
    -- column 삭제 하기
    ALTER TABLE news
    DROP COLUMN subtilte;

좋은 웹페이지 즐겨찾기