MVC | MTV | 역할 |
---|---|---|
Model | Model | 데이터 구조 정의, DB 기록 관리 등 데이터와 관련된 로직을 처리 |
View | Template | UI, 레이아웃 등 화면상의 로직을 처리 |
Controller | View | 클라이언트 요청에 대해 처리를 분기하는 역할 |
역할에 따라 분리하는 이유
- 관심사 분리
- 각 부분을 독립적으로 개발할 수 있어서 생산성이 증가하고 유지 보수가 쉬워짐
- 다수의 멤버가 동시에 개발하기도 용이함
순서도
1) HTTP 요청을 urls.py에서 수신
2) urls.py에서 HTTP 요청에 맞는 View로 이동
3) 해당 View에서 필요한 데이터를 Model과 송수신
4) 송수신한 데이터를 화면에 보여주기 위해 Template과 통신
5) 완성된 작업물을 HTTP 응답으로 내보냄
{{ variable }}
.
을 사용하여 변수의 속성 값에 접근 가능render()
의 세번째 인자인 context에 dict()
형태로 데이터가 넘겨짐key
값이 template에서 사용 가능한 변수가 됨{{ variable|filter }}
{% tag %}
{% if ~ %}
{% endif %}
{# 한 줄 주석 #}
{% comment %}
여러줄
주석
{% endcomment %}
코드의 재사용성을 높여 코드 중복 문제를 해결
상위 템플릿에 공통이 될 부분을 정의하고 하위 템플릿에서 달라질 부분을 block으로 만드는 skeleton 형태
상위 템플릿
- {% block block_name %}{% endblock block_name %}
- 상위 템플릿에서 하위 템플릿마다 달라질 부분을 정의
하위 템플릿
- {% extends 'template_name' %}
- 하위 템플릿에서 상위 템플릿을 상속한다는 의미
- 하위 템플릿의 최상단에 위 명령어가 위치해야함
- 다중 상속을 지원하지 않음
# users/urls.py
path("profile/<str:username>/", views.profile)
# users/views.py
def profile(request, username):
context = {"username": username}
return render(request, "profile.html", context)
# users/templates/profile.html
<h1>{{ username }} Profile Page</h1>
<p> username : {{ username }} </p>
.
|-- articles // `articles/` 요청을 처리하는 app
| ⁝
| |-- templates
| | |-- data-catch.html
| | |-- data-throw.html
| | |-- hello.html
| | |-- index.html
| |-- urls.py
| |-- views.py
|-- db.sqlite3
|-- manage.py
|-- my_first_pjt
| ⁝
| |-- settings.py
| |-- urls.py
|-- templates
| |-- base.html
|-- users // `users/` 요청을 처리하는 app
⁝
|-- templates
| |-- profile.html
| |-- users.html
|-- urls.py
|-- views.py
# /articles/urls.py
urlpatterns = [
path("hello/", views.hello, name="hello"),
# data
path("data-throw/", views.data_throw, name="data-throw"),
path("data-catch/", views.data_catch, name="data-catch"),
]
<!-- /articles/templates/index.html -->
<!-- href에 경로가 아닌 path의 name을 대신 적어서 경로를 표현 -->
{% block content %}
<h1>INDEX</h1>
<nav>
<ul>
<li><a href="{% url 'hello' %}">Hello</a></li>
<li><a href="{% url 'data-throw' %}">Data Throw</a></li>
<li><a href="{% url 'users' %}">Users</a></li>
</ul>
</nav>
<p>My first Django project is working!</p>
{% endblock content %}
modles.Model
을 상속받아서 사용하고자 하는 데이터 스키마를 정의from django.db import models
class Article(models.Model):
title = models.CharField(max_length=50) # Article table의 title column
content = models.TextField() # content column
created_at = models.DateTimeField(auto_now_add=True) # created_at column
updated_at = models.DateTimeField(auto_now=True) # updated_at column
python manage.py makemigrations
python manage.py migrate
python manage.py showmigration
python manage.py sqlmigrate <app_name> <migration_no>
objects
<Model Class>.<Manager>.<Queryset API>
Django shell: Django가 제공하는 여러가지 기능을 명령어로 입력해서 실행할 수 있는 shell 환경
CRUD: 대부분의 소프트웨어가 하는 동작인 Create, Read, Update, Delete의 앞 글자
생성(Create)
# 하나의 Article 생성 방법 (1)
article = Article()
article.title = 'first_title'
article.content = 'first_content'
# 여기에서 전체 Article을 조회해보면
Article.objects.all() # 비어있다
# save()하기전에는 저장되지 않음
article.save()
# 다시 전체 Article을 조회해보면 하나의 아티클이 있음
Article.objects.all()
# 속성 하나씩 접근하기
# 제목
article.title
# 내용
article.content
# 생성일시
article.create_at
# pk(id)
article.id
---
# 하나의 Article 생성 방법 (2)
article = Article(title='second_title', content='second_content')
article.save()
---
# 하나의 Article 생성 방법 (3)
# save()가 필요하지 않음
Article.objects.create(title='third title', content='마지막 방법')
# 하나의 Article만 조회하기 (get)
# 조회하는 대상이 하나도 없거나, 2개 이상이면 에러 발생
Article.objects.get(id=1)
---
# 전체 Article 조회
Article.objects.all()
---
# 조건으로 조회하기
# 조건에 사용되는 매개변수를 `lookup`이라고 함
# lookup과 일치되는 객체를 모두 반환
Article.objects.filter(title='second')
# 다양한 lookup을 제공
Article.objects.filter(id__gt=2) # 2보다 큰 id
Article.objects.filter(id__in=[1,2,3]) # 1,2,3에 속하는 id
Article.objects.filter(content__contains='my') # content에 'my'가 포함된
...
'''
1. 수정할 객체를 조회
2. 수정할 내용을 입력
3. 수정한 것을 DB에 반영
'''
article = Article.objects.get(id=1)
article.title = 'updated title'
article.save()
# 삭제할 객체를 조회한 후 삭제
article = Article.objects.get(id=2)
article.delete()