우선 앞부분에서 db연결을 마친 후 글을 써주면 다음과 같은 화면을 볼 수 있습니다.
저는 여기서 첫 페이지에 보이는 body글자 수를 제한한 뒤, '...더보기'를 누르면
상세보기 페이지로 넘어가도록 짜보려고 합니다.
1. 글자 수 제한하기
글자 수를 제한하기 위해 summary라는 함수를 만들어볼께요.
#models.py
def summary(self):
return self.body[:100]
2. index.html에서 글자 수를 제한한 뒤 '...더보기' 글자 추가 후 링크달기
#index.html
{% for blog in blogs.all %}
<h1> {{blog.title}} </h1>
<p> {{blog.pub_date}} </p>
<p> {{blog.summary}}<a href>...더보기</a></p>
<br><br>
{% endfor %}
3. 링크 url연결
자, 여기서 생각하셔야 할 부분이있습니다.
더보기를 누르면 detail.html로 넘어가야 하는데,
그럼 게시물 수 만큼의 detail.html을 만들어줘야 할까요?
그렇다면 너무 비효율적이겠죠?
그래서 우리는 detail.html 페이지는 하나만 만들고,
선택된 번호의 Blog 객체 내용을 띄우는 코드를 짜볼거에요.
그림과 같이 하나의 html에 n번째 객체를 보여주기 위해서는 다음과 같은 과정이 필요합니다.
1) n번째 블로그 객체를 요청하면 n번 객체의 내용을 띄우기. -> pk(primary key)
2) url => 사이트/detail/객체번호(n) -> path Converter
3) 없는 페이지, 즉 없는 객체를 요청하면 404 에러 띄우기 -> get_object_or_404 함수
우선 url부터 어떻게 설정해주어야 하는지 보겠습니다.
path('detail/<int:blog_id>',modelapp.views.detail,name="detail"),
path는 path('url이름', 함수이름, path이름)의 형태를 띄고 있습니다.
이때 <>를 path converter라고 하는데, <type(int, str 등): 변수이름>의 형태를 띄고 있습니다.
기존의 url 은 숫자를 쓰더라도 str 타입으로 인식을 하는데 <>와 int를 통해 정수형으로 바꿔줍니다.
이 <int:blog_id>는 '지정한 converter type(int)으로 변환한 변수(blog_id)를 view 함수로 넘겨라'라는
의미를 가지고 있습니다.
즉, 원래 url은 string type이지만, blog_id를 int형으로 변환하여 함수에게 넘겨준다는 거죠.
예를 들어 detail/1이 url을 부르게 되면 blog_id=1이 되어, blog_id를 view 함수로 넘어가게 됩니다.
이는 주로 계층적인 url을 다룰 때 사용합니다.
이제 views.py에서 함수를 만들 때,
이때까지 우리는 index.html을 달라고 요청이 들어올 때 index를 실행시키면 되었습니다.
def index(request):
blogs = Blog.objects #모델로부터 객체의 목록을 전달, 쿼리셋
return render(request,'index.html',{'blogs':blogs})
하지만 이제는 요청도 필요하지만, 몇 번째 블로그 객체에 대한 것인지도 필요합니다.
그래서 인자가 2개가 되는거죠.
(url에서 blog_id라는 변수로 보냈기에 함수에서 받을 때도 blog_id로 받음)
def detail(request, blog_id):
그리고 이제 번호에 해당하는 객체를 보내주어야 하는데,
이때 get_object_or_404함수를 이용합니다.
우선 import를 해주고요.
from django.shortcuts import render, get_object_or_404
def detail(request, blog_id):
blog_detail = get_object_or_404(Blog, pk=blog_id)
return render(request, '/detail.html', {'blogdetail': blog_detail})
get_object_or_404함수는 2개의 인자를 받는데,
get_object_or_404(어떤 클래스, 검색조건(pk)) 형태를 띈다.
우선 어떤 클래스로부터 정보를 가져올지에 대한 정보를 알려주어야 합니다.
우리는 Blog라는 클래스에서 정보를 가져오니 Blog라고 적어줍니다.
그리고 pk는 primary key의 약자로 모델에서 찍어낸 수많은 객체들을 구분할 수 있는 구분자라고 할 수 있습니다.
하나의 클래스에서 여러 게시물들이 찍어내질텐데, 이를 구분해주는 이름표 같은 거죠!
데이터를 구분 지을 수 있는 이름표, 데이터의 대표값으로 볼 수 있겠네요.
그러니 중족될 수 없는 단일 값이어야겠죠?
어떤 값을 데이터의 대표값으로 삼을지는 정의하기 나름입니다.
모델에서 따로 pk를 주지 않아도, pk는 꼭 필요한 아이라서
id가 자동으로 pk가 되어 식별자 역할이 됩니다.
다만 따로 pk를 주고 싶다면, 모델에서
class Blog(models.Model):
my_pk = models.IntegerField(primary_key=True)
우리는 url에서 blog_id로 받아왔으니, view에서도 blog_id를 pk를 가져와야합니다.
view는 urls.py에 적었던 pk를 식별하기 때문입니다.
자, 우리는 이제 blog 객체의 id값으로 데이터를 가져와,
있으면 보여주고 없으면 404 에러를 띄워줍니다.
예를 들어 db에 만든 적 없는 1000번째 url을 불러주면-
404에러가 보이쥬/
이때 객체의 id는 쟝고가 자동으로 만들어줍니다.
자 이제 url과 view를 만들어주었으니 main.html과 detail.html을 연결시켜줄께요!
main.html로 가서 a태그에 다음 url을 넣어줍니다.
{% for blog in blogcontent.all %}
<h1> {{blog.title}} </h1>
<p> {{blog.pub_date}} </p>
<p> {{blog.sum}}<a href="{% url 'detail' blog.id %}">...더보기</a></p>
<br><br>
{% endfor %}
더보기 링크에 {% url 'detail' blog.id %}이런 아이가 붙었죠.
이 blog.id가, 클래스에서 넘어오는 id가 각 객체에 자동으로 매겨지는 거죠.
이제 이를 누르면 'detail/객체번호'인 url로 넘어가겠죠?
그럼 그 detail.html은 어떤 형태를 띄고 있어야 할까요?
함수에서 가져온 blogdetail로 표현만 해주면 끝~
<h1> {{blogdetail.title}} </h1>
<p> {{blogdetail.pub_date}} </p>
<p> {{blogdetail.body}}</p>
<a href="{% url 'main' %}">돌아가기</a>
'개발 > Django_python 웹 프레임워크' 카테고리의 다른 글
Blog project_CRUD 2-수정, 삭제 만들기 (0) | 2020.07.12 |
---|---|
Blog project_Create 글쓰기 만들기/CRUD (0) | 2020.07.12 |
Django - Model & admin (1) | 2020.07.06 |
쟝고 기본 세팅 명령어 (1) | 2020.07.06 |
Django web 예제 - wordcount (0) | 2020.07.02 |
댓글