Sử dụng Generic View trong Python Django

Lập trình web với Python bằng Django

5.0 (1 đánh giá)
Tạo bởi Kteam Cập nhật lần cuối 15:19 01-12-2019 13.049 lượt xem 0 bình luận
Học nhanh

Danh sách bài học

Sử dụng Generic View trong Python Django

Ghi chú

Nội dung bài viết bạn đang xem được update từ tháng 06/2019. Vì vậy sẽ có đôi chút khác biệt giữa VIDEO và NỘI DUNG BÀI VIẾT.

Chúng ta sẽ có nhiều cập nhập hơn về cả bài viết lẫn video trong thời gian tới. Nhớ like / share hoặc đánh giá 5 sao để Kteam có động lực nhé! 

Cảm ơn các bạn! 


Dẫn nhập

Ở bài trước, Kteam đã hướng dẫn các bạn xong HƯỚNG DẪN XỬ LÝ  LOGIN VÀ LOGOUT USER TRONG PYTHON DJANGO

Trong bài này Kteam sẽ giới thiệu cho các bạn về cách sử dụng Generic View trong Django.


Nội dung

Để theo dõi bài này tốt nhất, bạn nên xem qua bài:

Bài này sẽ giới thiệu những nội dung sau:

  • Generic View là gì?
  • Sử dụng ListView và DetailView
  • Cách gọi Generic View tối giản hơn

Generic View là gì?

Viết những ứng dụng web có thể có những thứ không thay đổi, và từ đó ta sẽ lặp lại những pattern liên tục... Django cố gắng xử lý những đơn điệu đó tại pattern modeltemplate (view), nhưng lập trình viên website vẫn phải mệt nhọc xử lý tạo tầng view (controller).
Generic View được phát triển để giải quyết vấn đề đó. Người ta đã thu gom những cái chung của những kiến thức và mô hình ở view (controller) để phát triển và abstract chúng sao cho chúng ta có thể viết xử lý data trong views mà không cần viết code quá nhiều.
Chúng ta sẽ phát hiện ra có những task khá chung chung với nhau như: hiển thị list trong object, hiển thị thông tin chi tiết,...


Sử dụng ListView và DetailView

Bây giờ tại views của app blog, Kteam sẽ thay thế hàm list bằng class ListView, hàm post bằng class DetailView.
Ta sửa lại views.py như sau:

from django.shortcuts import render
from .models import Post
from django.views.generic import ListView, DetailView
# Create your views here.

class PostListView(ListView):
    queryset = Post.objects.all().order_by('-date')
    template_name = 'blog/blog.html'
    context_object_name = 'Posts'
    paginate_by = 10

class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/post.html'
  • import class ListViewDetailView.
  • khai báo class PostListView kế thừa ListView. Ta dùng queryset để lưu data truy vấn thay vì model (vì model sẽ thấy data từ trên xuống trong khi Kteam muốn lấy data theo thời gian từ cũ đến mới). Khai báo template_name, key của queryset. paginate_by là để phân trang, nghĩa là hiển thị ở template 10 bài đầu, rồi người dùng nhấn next thì mới xuất hiện 10 bài cũ hơn.
  • khai báo PostDetailView kế thừa DetailView. Vì DetailView sẽ truy vấn bằng primary key của model nên ta chỉ cần khai báo model để Django biết để truy vấn. Ngoài ra khai báo template_name.

Tiếp theo, ta sẽ sửa lại ở urls.py:

from django.urls import path
from . import views

urlpatterns = [
   path('', views.PostListView.as_view(), name='blog'),
   path('<int:pk>/', views.PostDetailView.as_view(), name='post'),
]
  • vì là class nên không thể đưa class thẳng vào url, ta sẽ gọi function as_view của class.
  • PostDetailView thì class sẽ truy vấn bằng primary key, nên thay url id thành pk để path hợp lệ.

Vì ở ListView ta có phân trang, nên ta chỉnh template thêm phần pagination:

{% extends "pages/base.html" %}
 
{% block title %}Blog{% endblock %}
 
{% block content %}
{% for post in Posts %}
    <h4>{{post.date|date:"d-m-Y"}}<a href="/redirect?Id=bPkSKQqMZ9erlLi6p21Q4A%3d%3d" url 'post' post.id %}">{{post.title}}</a></h4>
    <img src="{{post.image.url}}" width="500px" height="300px" />
{% endfor %}
<br/>
{% if page_obj.has_next %}
    <a href="/redirect?Id=5X7PNpoYSAf8ixnSnRj01TqsLDVRgREOSN1%2f%2fTHd3cqOH%2fnBsmGomt6wNekyuxMZtv4DKMfpRucdayOMARv5iK897ba1V6oesyqoyKTuvIU%3d" theo</a>
{% endif %}
{% endblock %}

  • Ta thêm điều kiện là nếu còn tiếp thì sẽ hiển thị thêm tag a tiếp theo với đường dẫn hiện tại kèm theo tham số page bằng số trang tiếp theo

Giờ ta thử kiểm tra, (Kteam sẽ cố tình chuyển paginate_by xuống bằng 1 để có thể kiểm tra link nhấn bài tiếp theo):


Cách gọi Generic View tối giản hơn

Nếu các bạn nhớ bài trước Kteam đã hướng dẫn dùng thư viện để login logout, bản chất nó cũng là generic view. Nếu các bạn nhớ cách viết thì ta có thể tối giản dòng code trên bằng cách viết như sau, tại urls.py app blog:

from django.urls import path
from .models import Post
from django.views.generic import ListView, DetailView

urlpatterns = [
   path('', ListView.as_view(
      queryset = Post.objects.all().order_by('-date'),
      template_name = 'blog/blog.html',
      context_object_name = 'Posts',
      paginate_by = 10)
      , name='blog'),
   path('<int:pk>/', DetailView.as_view(
      model = Post,
      template_name = 'blog/post.html'), 
      name='post'),
]

Kết luận

Trong bài này, chúng ta đã tìm hiểu cách Sử dụng Generic View.

Bài sau chúng ta sẽ cùng tìm hiểu về cách TẠO BÌNH LUẬN TRONG BÀI VIẾT.

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Và đừng quên “Luyện tập – Thử Thách – Không ngại khó


Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần BÌNH LUẬN bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.

Nội dung bài viết

Tác giả/Dịch giả

Khóa học

Lập trình web với Python bằng Django

Lập trình web với Python bằng Django

Đánh giá

phuly8989 đã đánh giá 07:52 03-09-2019

rất bổ ích , cám ơn Bạn

Bình luận

Để bình luận, bạn cần đăng nhập bằng tài khoản Howkteam.

Đăng nhập
Không có video.