간단하게 startapp blog 만 하고 이미지를 업로드한 게시물들의 목록과 검색 기능을 구현한 index와 게시물의 상세 정보를 볼 수 있는 post와 게시글을 작성하고 파일을 업로드 하는 write를 구현해보자.
실습
여태 했던 실습 내용을 참고하여 여기까지 만들어서 runserver 했을 때 http://127.0.0.1:8000/blog, http://127.0.0.1:8000/blog/write, http://127.0.0.1:8000/blog/1 이 다 잘 실행되는지 확인.
blog / models.py 에 DB 설계하기
아래 사이트를 참고
https://docs.djangoproject.com/en/4.2/ref/models/fields/
Django
The web framework for perfectionists with deadlines.
docs.djangoproject.com
이미지를 저장할거기 때문에 이미지 관련 라이브러리인 pillow 설치
pip install pillow
models.py 수정
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100) # 제목
contents = models.TextField() # 내용
main_image = models.ImageField(blank=True, null=True) # 이미지. blank=True : 이 필드는 필수가 아니다. null=True : 그 이전 게시물이 비어있어도 된다.
created_at = models.DateTimeField(auto_now_add=True) # 생성시간. auto_now_add=True : 지금 시간을 자동으로 넣는다.
updated_at = models.DateTimeField(auto_now=True)
def __str__(self): # 출력했을때 밖으로 보이는 것
return self.title
models.py 수정 후 입력
python manage.py makemigrations : DB를 조작할 수 있는 코드
python manage.py migrate : 실제 DB에 반영
blog / admin.py 수정
# blog / admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
python manage.py createsuperuser 로 admin계정 생성
이미지가 실제로 저장될 폴더 설정하기
settings.py 에 맨 마지막 줄에 추가
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
admin페이지에서 로그인 후, 게시물 작성해보기
게시물을 작성해보면 사진 파일이 blog / media / 사진.jpg 경로에 저장된것을 볼 수 있다.
이미지 url 연결하기.
tutorialdjango / urls.py 수정
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # 이미지 경로로 연결되는 url링크 추가
admin페이지에서 게시물에 첨부된 사진을 클릭하면 이미지 경로로 된 url이 연결된다.
templates / blog 에 부모 html 인 menu.html 생성
<h2>My Blog</h2>
<a href="{% url 'blog:index' %}">Main</a>
<a href="{% url 'blog:write' %}">Write</a>
{% block content %}
{% endblock %}
상속받는 html 파일들을 수정
blog / index.html
{% extends 'blog/menu.html' %}
{% block content %}
<h1>블로그 글 목록</h1>
<!-- input값을 get을 사용해서 ?q=검색할내용 으로 보냄 -->
<form action="" method="get">
<input name="q" type="search">
<button type="submit">검색</button>
</form>
<ul>
{% for i in db %}
<p><a href="{% url 'blog:post' i.id%}">{{i.title}}</a></p>
<p>{{i.created_at}}</p>
{% endfor %}
</ul>
{% endblock %}
blog / post.html
{% extends 'blog/menu.html' %}
{% block content %}
<h1>{{db.title}}</h1>
<p>{{db.contents}}</p>
<p>{{db.updated_at}}</p>
{% if db.main_image %}
<!-- db.main_image.url : image의 경로 -->
<img src="{{db.main_image.url}}">
{% endif %}
{% endblock %}
blog / write.html
{% extends 'blog/menu.html' %}
{% block content %}
<!-- post방식으로 form을 보내고, image를 보내려면 enctype을 꼭 적어야한다. -->
<form action="" method="post" enctype="multipart/form-data">
<!-- post방식으로 보낼때 csrf_token 꼭 적어야함 -->
{% csrf_token %}
<label for="title">제목</label>
<input id="title" name="title" type="text">
<label for="contents">내용</label>
<textarea id="contents" name="contents"></textarea>
<input type="file" name="image">
<button type="submit">저장</button>
</form>
{% endblock %}
blog / views.py 수정하기
views.py 수정
from django.shortcuts import render
from .models import Post
from django.db.models import Q
def index(request):
if request.GET.get('q'): # index.html에서 검색한 q의 값
q = request.GET.get('q')
# 데이터베이스를 연결해주는 ORM 코드
db = Post.objects.filter(Q(title__icontains=q) | Q(contents__icontains=q)).distinct()
# Post에서 title 또는 contents에 q를 대소문자 구분 없이 포함하는 것들을 중복을 제거해서 db로 하겠다.
else:
db = Post.objects.all() # q가 없으면 그냥 Post의 모든 요소를 db로
context = {'db': db}
return render(request, 'blog/index.html', context)
def write(request):
if request.method == 'POST': # POST 일때는 이렇게 처리
title = request.POST.get('title')
contents = request.POST.get('contents')
image = request.FILES.get('image')
if title and contents and image: # image가 있을 때
newpost = Post.objects.create(title=f'{title}', contents=f'{contents}', main_image=image)
newpost.save()
elif title and contents: # image가 없을 때
newpost = Post.objects.create(title=f'{title}', contents=f'{contents}')
newpost.save()
return index(request) # index로 넘어감
else: # POST 요청이 아닐때는 그냥 페이지 보여줌
return render(request, 'blog/write.html')
def post(request, pk):
db = Post.objects.get(pk=pk) # Post의 요소들중 pk가 pk인것을 db로
context = {'db': db}
return render(request, 'blog/post.html', context)
결과
write에서 글을 쓰고 파일을 올리면 DB에 추가된다.
'Django' 카테고리의 다른 글
Django 실습(5) Form과 ModelForm 사용한 블로그 (0) | 2023.10.12 |
---|---|
Django ORM을 이용해서 DB CRUD 해보기 (0) | 2023.10.11 |
Django 실습(3) Bootstrap 사용해서 블로그 만들고 꾸미기 (0) | 2023.10.10 |
Django 실습(2) Templates 분리와 상속으로 블로그 만들기 (1) | 2023.10.10 |
Django 실습(1) 핫딜 크롤링해서 상품 사이트 만들기 (0) | 2023.10.05 |