작년 한 해 동안 멋사를 통해 장고를 공부했긴 했지만, '일단 따라해보자 !', '그냥 욱여넣어봐 !'와 같은 마음 가짐으로 임했던지라... 제대로 기억이 나지 않는다.. ㅠㅠ 따라서 모든 일상이 코로나로 부숴져버렸지만, 부숴진 일상의 빈틈이 생겨난 만큼 장고도 복습할 겸 (누구도 시키지 않은) 개인 프로젝트를 해보고자 한다 ! 빠샤👊🏻
django는 "보편적인 웹 개발 업무를 빠르고 쉽게 만들어주도록" 설계된 웹 프레임워크
django는 데이터베이스 없이 사용할 수 있어 ?
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값으로 표현된다
$ python manage.py makemigrations
$ python manage.py migrate
makemigrations
: 생성 가능한 모델을 찾아 테이블이 존재하지 않을 경우 마이그레이션 생성migrate
: 마이그레이션을 실행하고 사용자의 데이터베이스에 테이블을 생성
과연 장고는 어떻게 데이터를 주고받고, 이를 삽입, 수정, 삭제할 수 있을지 보자 !
# "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를 제공해 준다 !
from django.contrib import admin
from . import models
admin.site.register(models.Article)
- "깔끔하고 우아하게 URL을 설계할 수" 있는 장점을 가진다.
.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),
]
※ 이 경로들은 로드 시 정규표현식으로 컴파일 되기 때문에 엄청나게 빠르다.
뷰는 무슨 일을 해?
- 요청된 페이지의 내용을 담고있는 HttpResponse 객체 반환
- 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 %}
{{ 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 함수)
맨 위에 있는
{% extends "base.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 공식 홈페이지에 나온 장고의 인트로 내용은 여기까지이다.
이제 직접 설치하고 만들면서 다시 익혀야지 ✍💻
튜토리얼 내용을 잘 정리하셨네요! 잘 보고 갑니다.👍