43 blogs 상세 페이지 만들기 - detail

43.1 Django 상세 페이지 등록 - urls.py

urls에 blog/pk 로 경로를 설정합니다.

blog/1, blog/2 ... 으로 들어오는 경로에 대한 설정입니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#myapp/blog/urls.py
from django.urls import path
from . import views

app_name = "blog"

urlpatterns = [    
    # path("index.do", views.index.as_view(), name="main"), 
    path("", views.firstIndex.as_view(), name="first_index"),
    path('blogs/', views.blogList.as_view(), name='blog_list'),
    path('blog/<int:pk>/', views.blogDetail.as_view(), name='blog_detail'), 
]

43.2 Django 상세 페이지 등록 - view.py

목록은 generic.ListView를 이용해 작업했다면
상세는 generic.View를 이용했습니다.

View는 blogDetail이 호출되면 get, post로 찾게 되됩니다.

get 방식으로 호출되면 get함수를,
post 방식으로 호출되면 post 함수를 실행합니다.

get_queryset() 함수 실행시
values에 related_name으로 컬럼을 정의하여 PyBlog 와 PyBlogDetail 모델이 조인이 되도록 했습니다.

※ 두 모델사이에 FK가 설정되어 있어 자동으로 조인됩니다.
※ related_name은 PyBlogDetail 모델에 정의되어 있습니다.
40.3 장고 모델 등록
※ 장고에서는 blogList 처럼 간결한 뷰 작성을 권장하고 있습니다.
※ generic.View는 사용하면 get, post를 구현하기에 소스가 더 복잡해 볼 수 있지만, 저는 generic.View로 구현하는게 더 익숙하고 편안합니다.(구시대 개발.ㅠㅠ)

다음 시간에는 장고 철학에 맞게 view를 다듬어 보겠습니다. ^^

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#myapp/blog/views.py

class blogDetail( generic.View):
    def __init__(self):
        self.template_name  = "blog/blogDetail.html" 

    def get_queryset(self):     
        results = PyBlog.objects.filter(id=self.kwargs['pk'])       
        results = results.values('id','title','update_dt','regist_dt',
                                'pb_detail__detail_id',
                                'pb_detail__sub_title','pb_detail__img_url','pb_detail__img_size',
                                'pb_detail__content_body')

        #print("blogDetail results.query : ", results.query)

        self.title_nm = results[0]['title']
        self.descript = results[0]['pb_detail__content_body'][:320]
        self.ogImgUrl = results[0]['pb_detail__img_url']
        return results

    def get(self, request, *args, **kwargs):        
        self.content = {"dataList":self.get_queryset(),
                        "descript":self.descript,"title_nm":self.title_nm,"ogImgUrl":self.ogImgUrl}

        return render(request, self.template_name, self.content)

43.3 Django 상세 페이지 등록 - blogDetail.html

뷰에 정의한 dataList에서 데이터를 화면에 표시한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{% extends "base/base.html" %}
{% block content %}
<div class="container-fluid">
    <h1 class="mt-4">{{title_nm}}</h1>
     <div class="row">
        <div class="col-xl-10">
            <div class="card mb-4">
            {% for list in dataList %}                              
                <div class="card-header py-3">                
                    <h2 class="m-1 font-weight-bold text-dark"><span id="{{list.pb_detail__sub_title}}">{{list.pb_detail__sub_title}}</span>
                    </h2>
                </div>
                <div class="card-body">
                    {% if list.pb_detail__img_url %}
                    <div class="text-center">
                         <img class="img-fluid px-3 px-sm-4 mt-3 mb-4" style="width: {{list.pb_detail__img_size}}rem;" src="{{list.pb_detail__img_url}}"/>                    
                    </div>
                    {% endif %}                    

                    <div class="mb-2 pl-4">{{ list.pb_detail__content_body }}</div>                                                            
                </div>               
            {% endfor %}
            </div>
        </div>       
    </div>
</div>
{% endblock %}

43.4 Django 목록에 상세 페이지 링크 걸기 - url

42.3 Django 목록 페이지 등록 - list.html에서 작성한 소스에 상세페이지 링크를 추가합니다.

※ blog:blog_detail 은 url을 좀 더 명확하게 해주며, 동적으로 관리되어 업그레이드, 리팩터링을 진행할때 좀 더 편하게 해주는 장점있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!-- templates/blog/PyBlog_list.html -->
{% extends "base/base.html" %}
{% block content %}
<div class="container-fluid">
    <h1 class="mt-4">Python Blogs</h1>

     <div class="row">
        <div class="col-xl-8">
            <div class="card mb-4">
            {% for list in object_list %}  
                <div class="card-header">                   
                    <p><a href="{% url 'blog:blog_detail' list.id %}">{{list.title}}</a></p>
                </div>
            {% endfor %}              
            </div>
        </div>
    </div>
</div>
{% endblock %}

43.5 브라우저에서 상세페이지 확인하기

목록에서 상세페이지로 연결이 잘 되는지 확인합니다.

성공!! ^^