PK, Path Converter, 예외처리
models.py의 Blog 클래스 안에 본문 미리보기가 100글자 까지만 보이도록 하는 함수를 작성
class Blog(models.Model):
title = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
body = models.TextField()
def __str__(self):
return self.title # 글 제목이 타이틀로 보이도록
def summary(self):
return self.body[:100] # 본문 미리보기가 100글자 까지만 보이도록
home.html 파일에 함수를 넣어주면,,
{% for blog in blogs.all%}
<h1>제목: {{blog.title}}</h1>
<p>날짜: {{blog.pub_date}}</p>
<p>본문 미리보기: {{blog.summary}}</p>
<br><br>
{%endfor%}
이제 html 파일 상에 ‘…more’를 a링크를 달아서 넣어주고,,
{% for blog in blogs.all%}
<h1>제목: {{blog.title}}</h1>
<p>날짜: {{blog.pub_date}}</p>
<p>본문 미리보기: {{blog.summary}} <a href="{% url %}">...more</a></p>
<br><br>
{%endfor%}
이제 a링크를 클릭했을 때, 본문 전체를 보여주는 detail.html 파일로 이동하게 해보자
views.py
from django.shortcuts import get_object_or_404, render
from .models import Blog
def home(request):
blogs = Blog.objects #쿼리셋 -> 모델의 Blog 객체 목록을 변수에 저장
return render(request, 'home.html', {'blogs': blogs})
def detail(request, blog_id):
blog_detail = get_object_or_404(Blog, pk= blog_id) #이용자가 원한 몇 번 블로그 객체
return render(request, 'detail.html', {'blog':blog_detail})
home.html에서 id 정보와 함께 링크를 연결!
<p>본문 미리보기: {{blog.summary}} <a href="{%url 'detail' blog.id%}">...more</a></p>
detail.html 내용을 구성
<h1>자세한 본문 내용입니다.</h1>
<br><br>
<h1>제목: {{blog.title}}</h1>
<p>날짜: {{blog.pub_date}}</p>
<p>자세한 본문: {{blog.body}}</p>
시간 템플릿 태그 표기
글쓰기 페이지 만들기
글을 입력하기 위해 일일이 admin 페이지에 들어가지 말고 글쓰기 페이지를 만들어보자
new.html을 생성해서 urls.py, views.py에 연동하고 대략적인 form을 구성했다
<div style="margin: 2rem;">
<form action="">
<h3>제목:</h3>
<input type="text" name="title">
<br><br>
<h3>본문:</h3>
<textarea cols="40" rows="10" name="body"></textarea>
<br><br>
<input class="btn btn-dark" type="submit" value="제출하기">
</form>
</div>
views.py에서 새로운 함수를 활용할 것이기 때문에 action을 create라는 임의의 url로 보내자
<form action="{% url 'create' %}">
urls.py에 임의의 해당 url을 생성하자 (html을 띄우는 것이 아니라 함수를 실행하기 위한 url)
path('blog/create/',blog.views.create, name="create"),
views.py에 form의 글을 DB로 보내는 create 함수를 만들어주자
def create(request): #new.html의 form에서 입력받은 내용을 DB로 넣어주는 함수
blog = Blog()
blog.title = request.GET['title']
blog.body = request.GET['body']
blog.pub_date = timezone.datetime.now()
blog.save() #객체에 해당하는 내용들을 /admin 에 저장
return redirect('/blog/'+str(blog.id)) #글 작성을 완료하면 해당 글 detail이 뜨도록
redirect() 함수를 활용하면 바로 해당 url로 이동한다
Static 다루기
블로그에 포트폴리오 탭을 추가하면서 정적 파일에 대해 알아보자
Static으로 미리 준비해둔 사진을 띄우고 Media를 통해 사진을 업로드해보자
새로운 Portfolio 앱을 만들고 settings.py에 등록, views에 등록, urls.py에 import 후 링크를 생성했다
portfolio 앱 내부에 static 폴더를 만들고 settings.py에서 파일을 모으도록 지정해줘야 한다
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'portfolio', 'static')
] # static 파일들이 현재 어디에 있는지
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# static 파일들이 어디로 모일 것인지
settings.py 하단에 이렇게 써주고,,
static 파일을 사용할 html 파일 최상단에 템플릿 태그를 넣어주자
{% load static %}
<!doctype html>
이제 html 상에 img 태그와 템플릿 태그로 static 파일을 넣어주면 된다!
<img src="{% static '티벳토끼.jpg' %}" width="100%" height="225" alt="비스카차">
Media 다루기
settings.py에서 업로드 될 파일(Media)을 저장할 디렉토리 경로와 URL을 지정해줘야 한다
settings.py 하단에 이렇게 추가해주자
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'portfolio', 'static')
] # static 파일들이 현재 어디에 있는지
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# static 파일들이 어디로 모일 것인지
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
이제 urls.py에서 두가지 import를 해주고 path를 추가해주면 되는데,,
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
url을 타고 온 파일을 DB에 넣어주는 작업을 해주자
models.py에 데이터를 받아줄 형식을 Class로 정의하고,,
class Portfolio(media,Model):
title = models.CharField(max_length=255)
image = models.ImageField(upload_to='images/')
description = models.CharField(max_length=500)
def __str__(self):
return self.title
이미지를 DB에 넣으려면 bash에 pip 하나를 더 설치해줘야 한다
이후 admin.py에도 연동해준다
from django.contrib import admin
from .models import Portfolio
admin.site.register(Portfolio)
이제 views.py에서 DB의 Portfolio 데이터를 출력하도록 함수를 수정하자!
from django.shortcuts import render
from .models import Portfolio
def portfolio(request):
portfolios = Portfolio.objects
return render(request, 'portfolio.html', {'portfolios':portfolios})
쿼리셋과 all 메소드, 템플릿 태그로 HTML 상에 띄우는 작업을 해주자
{%for portfolio in portfolios.all %}
<div class="col">
<div class="card shadow-sm">
<img src="{{portfolio.image.url}}" width="100%" height="225">
<div class="card-body">
<p class="card-text">{{portfolio.description}}</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
<button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
</div>
<small class="text-muted">9 mins</small>
</div>
</div>
</div>
</div>
{%endfor%}
반복할 부분을 잡아주고 내용도 탬플릿 변수로 수정해준다
이제 /admin에서 데이터를 추가히면 사이트에 차례대로 띄워진다
템플릿 상속
settings.py의 TEMPLATES 탭의 ‘DIRS’에 프로젝트 폴더와 templates 폴더를 써주자
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['secondproject/templates'],
이제 base.html에 공통적인 부분을 넣어주고
내용을 넣을 부분에 해당 코드를 넣어준다
<!--여기에 컨텐츠-->
{% block contents %}
{% endblock %}
<!--여기에 컨텐츠-->
이후 다른 html 파일들은 base.html 파일로 보낸 내용을 삭제하고, base.html을 불러오는 코드를 넣어준다
{% extends 'base.html' %}
{% block contents %}
<body>
<div>
<!--안겹치는 부분-->
<div style="margin: 1.5rem;">
<br>
<h2>{{blog.title}}</h2>
<p>{{blog.pub_date}}</p>
<p>{{blog.body}}</p>
</div>
<!--안겹치는 부분-->
</div>
</body>
{% endblock %}
URL 관리
대규모 프로젝트에서 앱이 추가/삭제되거나 다른 프로젝트에서 앱을 활용할 수도 있는데,,
예를 들어 blog/… url들을 관리하려면 해당 App 안에 urls.py 파일을 생성해준다
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('<int:blog_id>', views.detail, name="detail"),
path('new/', views.new, name="new"),
path('create/', views.create, name="create"),
]
이런 식으로 간략하게 코드를 받아온다
원래 urls.py에는 include를 import해주고 옮겨간 url들은 삭제해준다
from django.urls import path, include
대신 urlpatterns에 이렇게 넣어준다
urlpatterns = [
path('admin/', admin.site.urls),
path('', blog.views.home, name="home"),
path('blog/', include('blog.urls')), # App의 urls.py에 옮겨간 url들
path('portfolio/', portfolio.views.portfolio, name="portfolio"),
]
이렇게 폴더별로 url들을 관리할 수 있게 되었다!
본 내용은 멋쟁이사자처럼의 '9기 운영진 교육'을 바탕으로 작성되었습니다.
'Back-end > Django' 카테고리의 다른 글
[HUFS/HUFStudy] #6 Form (4) | 2021.07.30 |
---|---|
[HUFS/HUFStudy] #5 로그인/회원가입, Pagination (8) | 2021.07.28 |
[HUFS/HUFStudy] #3 Model/Admin, Queryset/Method (0) | 2021.07.14 |
[HUFS/HUFStudy] #2 Word Counter 만들기 (0) | 2021.07.03 |
[HUFS/HUFStudy] #1 기본 환경 세팅 (0) | 2021.06.29 |