[다시, 장고]Django - Intro

Adela·2020년 6월 24일
1

다시, 장고

목록 보기
1/6
post-thumbnail
post-custom-banner

작년 한 해 동안 멋사를 통해 장고를 공부했긴 했지만, '일단 따라해보자 !', '그냥 욱여넣어봐 !'와 같은 마음 가짐으로 임했던지라... 제대로 기억이 나지 않는다.. ㅠㅠ 따라서 모든 일상이 코로나로 부숴져버렸지만, 부숴진 일상의 빈틈이 생겨난 만큼 장고도 복습할 겸 (누구도 시키지 않은) 개인 프로젝트를 해보고자 한다 ! 빠샤👊🏻

Django 훑어보기

django는 "보편적인 웹 개발 업무를 빠르고 쉽게 만들어주도록" 설계된 웹 프레임워크

목표

  • django가 어떻게 동작하는지 이해하기

모델 설계

django는 데이터베이스 없이 사용할 수 있어 ?

  • 데이터베이스 레이아웃을 파이썬 코드로 표현할 수 있는 object-relational mapper가 같이 딸려 온다.
  • 예제
from django.db import models

class Reporter(models.Model):
	full_name = models.CharField(max_length=70)
    
    def __str__(self):
    	return self.full_name
    # 모델 클래스의 객체의 문자열 표현을 리턴함 
    # admin 페이지에서 확인하면 테이블에 생성된 객체가 full_name값으로 표현됨 
        
class Article(models.Model):
	pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
    
    def __str__(self):
    	return self.headline  
    # 따라서 이 경우, Article 테이블에 생성된 객체는 headline값으로 표현된다 

설치하기

  • 데이터베이스를 자동으로 생성해주는 Django command-line 유틸리티를 실행한다.
$ python manage.py makemigrations
$ python manage.py migrate
  1. makemigrations : 생성 가능한 모델을 찾아 테이블이 존재하지 않을 경우 마이그레이션 생성
  2. migrate : 마이그레이션을 실행하고 사용자의 데이터베이스에 테이블을 생성

자유로운 API 즐기기

과연 장고는 어떻게 데이터를 주고받고, 이를 삽입, 수정, 삭제할 수 있을지 보자 !

# "news" 라는 app이 있다고 가정하고, 그 앱에 생성한 models을 불러온다.
>>> from news.models import Article, Reporter

# 아직 Reporter에는 아무것도 없음
>>> Reporter.objects.all()
<QuerySet []>

# 새 Reporter를 만들기
>>> r = Reporter(full_name = 'Yangwon Kim')

# 데이터베이스에 저장하기. save()를 불러 저장한다.
>>> r.save()

# 이제 이 데이터는 id값을 가진다.
>>> r.id
1

# 이제 새로운 reporter가 데이터베이스 안에 생겼다.
>>> Reporter.objects.all()
<QuerySet [<Reporter: Yangwon Kim>]>

# 필드 값은 Python object에 애트리뷰트로 나타난다.
>>> r.full_name
'Yangwon Kim'

# 장고가 제공해주는 많은 데베 검색 API들 
>>> Reporter.objects.get(id=1)
<Reporter: Yangwon Kim>
>>> Reporter.objects.get(full_name__startswith='Yangwon')
<Reporter: Yangwon Kim>
>>> Reporter.objects.get(full_name__contains='im')
<Reporter: Yangwon Kim>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last)
	...
DoesNotExist: Reporter matching query does not exist

# article 만들어보기 
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Hello world', ... content='Hello Korea', reporter=r)
# pub_date = 오늘 날짜, head_link = 제목은 Hello world, content = 내용은 Hello Korea, reporter = 작성자는 r값 
>>> a.save()

# 이제 article이 데베 안에 생김
>>> Article.objects.all()
<QuerySet [<Article: Hello world>]>

# Article object는 관련된 Reporter object에 접근할 수 있는 API 겟또 !
>>> r = a.reporter
>>> r.full_name
'Yangwon Kim'

# 이 API를 통해 Article의 object를 reporter를 이용해서 불러올 수 있음 
>>> Article.objects.filter(reporter__full_name__startwith='Yangwon')
<QuerySet [<Article: Hello world>]>

# 물론 애트리뷰트 값을 바꿔서 object를 수정해줄 수도 있음. 예를 들어 이름을 바꾼다면
>>> r.full_name = 'Adela Kim'
>>> r.save()

# object 삭제는 이렇게 함
>>> r.delete()

동적인 관리자 인터페이스

장고의 가장 큰 장점 중 하나 : 준비된 administrative interface를 제공해 준다 !

  • 인증된 관리자가 object들을 추가, 삭제, 수정 다 할 수 있다.. 권한 짱짱
from django.contrib import admin

from . import models

admin.site.register(models.Article)

URL 설계

  1. "깔끔하고 우아하게 URL을 설계할 수" 있는 장점을 가진다.
  2. .php, .asp와 같은 불필요한 내용을 넣지 않는다.
from django.urls import path

from . import views

urlpatterns = [
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
    path('articles/<int:year>/<int:month>/<int:pk>/', views.article_detail),
]
  • url 경로들을 파이썬 콜백 함수들("views")로 연결해준다.
  • 경로를 나타내는 문자열들은 매개 변수 태그를 사용하여 url로부터 값을 "캡쳐" 한다.
  • 사용자가 페이지를 요청하면, django는 각 경로를 순서대로 실행하고, 요청된 url과 일치하는 첫번째 것에서 정지한다.
    if (아무것도 매치하는게 없다면) return 404 view 호출

※ 이 경로들은 로드 시 정규표현식으로 컴파일 되기 때문에 엄청나게 빠르다.

  • url 패턴 중 하나가 일치하면 django는 주어진 뷰를 호출한다.
  • 뷰: 파이썬 함수 -> 각각의 뷰에 "요청 메타데이터가 포함된 요청 개체"와 "패턴에 잡힌 값"이 전달된다.
    ex. 사용자 요청: URL "/articles/2005/05/39323/"
    django의 호출 : news.views.article_detail(request, year=2005, month=5, pk=39323)

뷰(View) 작성

뷰는 무슨 일을 해?

  1. 요청된 페이지의 내용을 담고있는 HttpResponse 객체 반환
  2. Http404 같은 예외 발생
  • 일반적으로 뷰는 파라미터들에 따라 데이터를 가져오며, 템플릿을 로드하고, 템플릿을 가져온 데이터로 렌더링 한다.
  • 예제
from django.shortcuts import render

from .modes import Article

def year_archive(request, year):
	a_list = Article.objects.filter(pub_date__year = year)
    context = {'year':year, 'article_list':a_list}
    return render(request, 'news/year_archive.html', context)
    # year_archive.html에서 태그를 불러 사용할 context

나만의 템플릿 작성

위의 view 코드는 news/year_archive.html 템플릿을 로드한다.

장고는 내가 만든 여러 템플릿들 중 중복을 최소화할 수 있게 하는 템플릿 검색 경로를 가지고 있다.

  • setting에서 DIRS 템플릿을 확인하기 위한 디렉토리의 목록을 명시한다.

  • 만약 첫번째 디렉토르에 템플릿이 존재하지 않으면 > 두번째 디렉토리, 그 외 디렉토리를 점검

  • 예제 (news/year_archive.html 템플릿을 발견했다면)

{% extends "base.html" %}

{% block title %}Articles for {{ year }}{% endblock %}

{% block content %}
<h1>Articles for {{ year }}</h1>

{% for article in article_list %}
    <p>{{ article.headline }}</p>
    <p>By {{ article.reporter.full_name }}</p>
    <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}
  • 이중괄호 변수
    ex. {{ article.headline }} : article의 headline 애트리뷰트 값을 출력한다.
  • {% for article in article_list %} 의 article_list은 view에서 context로 부른 ' article_list' 이다.

cf. {{ article.pub_date|date:"F j, Y" }} : 유닉스 스타일의 “파이프”(“|” 문자)
이 파이프는 템플릿 필터를 호출하며 이를 통해 변수의 값을 필터링 할 수 있다.
이 코드에서 date 필터는 파이썬의 datetime 개체를 지정한 포맷으로 변환 시킨다. (like PHP의 date 함수)

django의 템플릿 상속

맨 위에 있는 {% extends "base.html" %} 코드는 무슨 일을 하는지 ?

  • "한 뭉치의 block들이 정의된 'base' 라는 템플릿을 먼저 로드하고, 뒤따르는 block들로 이 block들을 채운다"는 거라는 데...
  • 여러 html 파일마다 공통적으로 사용되는 코드를 base.html에 작성해놓고, 필요한 html 파일에 {% extends "base.html" %} 만 써주면 똑같아 진다는 소리다.
  • 템플릿 안의 중복을 극적으로 낮추는 것.
  • 예제
{% load static %}
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="{% static "images/sitelogo.png" %}" alt="Logo">
    {% block content %}{% endblock %}
</body>
</html>

django 공식 홈페이지에 나온 장고의 인트로 내용은 여기까지이다.
이제 직접 설치하고 만들면서 다시 익혀야지 ✍💻

profile
개발 공부하는 심리학도
post-custom-banner

2개의 댓글

comment-user-thumbnail
2020년 7월 6일

튜토리얼 내용을 잘 정리하셨네요! 잘 보고 갑니다.👍

1개의 답글