''
'blog/'
'blog/test'
'blog/<int:pk>/'
앱의 데이터 구조와 동작을 정의하며, 데이터베이스와의 상호작용을 관리한다.
# blog > models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
contents = models.TextField()
created_at = models.DateTimeField(auto_now_add=True) # 처음 생성될 때에만 자동으로 현재 시간으로 설정
updated_at = models.DateTimeField(auto_now=True) # 수정될 때마다 자동으로 현재 시간으로 업데이트
실제 DB를 다루기 전에 확인 가능한 명세서 생성
python manage.py makemigrations
python manage.py migrate
admin.py
에서 설정하며 admin 사이트에서 데이터를 생성, 조회, 수정, 삭제하는 등의 작업을 웹 인터페이스로 수행 가능하다.
# blog > admin.py
from django.contrib import admin
from .models import Post
# Post 모델의 데이터를 admin 사이트에서 보고, 새로운 Post 데이터를 생성하고,
# 기존의 Post 데이터를 수정하거나 삭제할 수 있습니다.
admin.site.register(Post)
python manage.py createsuperuser
위의 과정까지 진행한 후, 서버를 실행하면 게시물의 제목이 Object... 이런 이상한 형식으로 출력된다.
이는 어떤 것이 제목인지를 명시하지 않아서인데, models.py
에서 __str__
메서드로 원하는 문자열로 출력하게끔 할 수 있다.
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
contents = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# 명칭이 제대로 나오도록 정의
def __str__(self):
create_time = self.created_at.strftime("%Y-%m-%d %H:%M:%S")
update_time = self.updated_at.strftime("%Y-%m-%d %H:%M:%S")
return f"제목: {self.title}, 생성시간: {create_time}, 수정시간: {update_time}"
# blog > views.py 수정
from django.shortcuts import render
from .models import Post
def blog_list(request):
# Post 클래스의 모든 객체를 가져와 blogs에 저장
blogs = Post.objects.all()
context = {"db": blogs}
# 템플릿에 전달
return render(request, "blog/blog_list.html", context)
def blog_detail(request, pk):
# pk값이 인자와 일치하는 Post 객체를 가져와 blog에 저장
blog = Post.objects.get(pk=pk)
context = {"db": blog}
return render(request, "blog/blog_detail.html", context)
def blog_test(request):
return render(request, "blog/blog_test.html")
위와 같이 모델의 Post
클래스 객체를 가져와 사용하도록 한다.
context
안에는 title, contents, created_at, updated_at이 들어 있다. 이를 db
라는 키로 접근한다.
게시물 제목으로 하이퍼링크를 생성하여 화면상에서 클릭하면 detail 페이지로 들어가도록 구현하였다.
# templates > blog > blog_list.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>게시판</h1>
<ul>
{% for post in db %}
<li>
# 블로그 글 리스트 하이퍼링크 생성
# 해당 링크를 누르면 blog_detail로 들어가도록 구현. 인자로 post.pk를 줌
<a href="{% url 'blog_detail' post.pk %}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
<p>{% url 'blog_list' %}</p>
<p>{% url 'blog_detail' 1 %}</p>
</body>
</html>
db의 데이터 개수만큼 링크를 생성하는 코드이다.
# templates > blog > blog_detail.html
<!DOCTYPE html>
<html lang="ko">
<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>blogdetail</title>
</head>
<body>
<h1>blogdetail</h1>
<h2>{{ db.title }}</h2>
<p>{{ db.contents }}</p>
<p>{{ db.created_at }}</p>
<p>{{ db.updated_at }}</p>
# blog_list로 돌아가는 목록 하이퍼링크 생성
<a href="{% url 'blog_list' %}">목록</a>
</body>
</html>
세부 페이지에서 목록이라는 링크를 클릭하면 원래의 blog_list 페이지로 돌아가게끔 하였다.
파이썬 문법을 통해 DB를 조작할 수 있는 편리한 기술(모델 클래스와 DB의 테이블을 자동으로 연관지어 주는 기술) 이다.
이번 예제에서는 간단한 CRUD 확인을 위하여 manage.py
의 쉘을 사용한다.
python manage.py shell
데이터를 읽어오는 문법이다.
>>> from blog.models import Post
>>> Post.objects.all()
>>> Post.objects.all().order_by('-pk')
-pk
라고 하면 내림차순 정렬이다.
>>> Post.objects.count()
>>> q = Post.objects.get(id=1)
>>> q
get
메서드는 조건에 맞는 하나의 데이터를 조회한다. 데이터가 2개 이상이면 예외를 발생한다.
filter
메서드는 조건에 맞는 모든 데이터를 조회한다. 데이터가 없어도 예외를 발생시키지 않는다.
get
은 유일한 필드를 조회하는 데에 사용되며, filter
는 특정 조건에 맞는 모든 데이터를 조회하거나 데이터의 존재 여부를 확인하는 데에 사용한다.
>>> Post.objects.filter(title__contains='1')
데이터를 불러오는 조건으로 연산자를 활용할 수도 있다.
eq
: 해당 조건과 같은지 판별ne
: not equallt
: little(미만)le
: little or equal (<=)gt
: greater(초과)ge
: greater or equal (>=)>>> Post.objects.filter(id__lt=3)
위와 같이 사용하면 id가 3 미만인 것만 필터링하여 가져온다.
데이터를 생성하는 문법이다.
>>> q = Post.objects.create(title='c4', contents='c44')
create
는 save
라는 문법이 필요 없지만, 글을 생성하고 수정하고 save
를 안하는 경우가 있어 무조건 하는 것을 추천한다고 한다.
>>> q.save()
데이터를 삭제하는 문법이다.
>>> q = Post.objects.get(pk=3)
>>> q.delete()
(1, {'blog.Post': 1})
detele
뒤에 출력된 문구는 삭제된 객체가 1개이며, 그 중 blog.Post 모델의 객체가 1개라는 것이다.
데이터를 수정하는 문법이다.
>>> q = Post.objects.all()[0]
>>> q.title
'1'
>>> q.title = 'hello world1'
>>> q
<Post: 제목: hello world1, 생성시간: 2024-02-23 02:39:11, 수정시간: 2024-02-23 02:39:11>
q의 원래 제목은 1
이었지만, hello world1
로 변경된 것을 볼 수 있다.
이를 통해 웹에서 게시물 CRUD를 UI와 함께 진행할 수 있다.
# blog > urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.blog_list, name="blog_list"),
path("<int:pk>/", views.blog_detail, name="blog_detail"),
path("create/<str:title>/", views.blog_create, name="blog_create"),
path("delete/<int:pk>/", views.blog_delete, name="blog_delete"),
path("test/", views.blog_test, name="test"),
]
# blog > views.py
from django.shortcuts import render, redirect
from .models import Post
def blog_list(request):
blogs = Post.objects.all()
context = {"db": blogs}
return render(request, "blog/blog_list.html", context)
def blog_detail(request, pk):
blog = Post.objects.get(pk=pk)
context = {"db": blog}
return render(request, "blog/blog_detail.html", context)
def blog_create(request, title):
contents = f"hello world {title}"
q = Post.objects.create(title=title, contents=contents)
q.save()
return redirect("blog_list")
def blog_delete(request, pk):
q = Post.objects.get(pk=pk)
q.delete()
return redirect("blog_list")
def blog_test(request):
return render(request, "blog/blog_test.html")