Trong phần này chúng ta sẽ tùy chỉnh lại hệ thống Admin đã được trình bày trong bài Hệ thống Admin.
Tùy chỉnh form
Khi chúng ta đăng ký các lớp model Question
và Choice
bằng hàm admin.site.register()
, Django sẽ dựa vào các thuộc tính mà chúng ta khai báo trong các lớp đó để hiển thị form trên trang admin. Chúng ta có thể quy định Django chỉ chọn một số thuộc tính được phép hiện ra để chỉnh sửa, thay vì hiện ra hết, bởi vì khi làm một ứng dụng có sử dụng CSDL, có những thuộc tính mà bạn muốn máy tính tự động sinh ra chứ không phải do con người nhập vào, chẳng hạn như ID, ngày giờ…
Chúng ta sẽ thay đổi bằng cách sửa lại code trong file polls/admin.py
.
from django.contrib import admin # Register your models here. from .models import Question, Choice class QuestionAdmin(admin.ModelAdmin): fields = ['pub_date', 'question_text'] admin.site.register(Question, QuestionAdmin) admin.site.register(Choice)
Việc này làm rất đơn giản, chúng ta chỉ cần viết một lớp kế thừa từ lớp admin.ModelAdmin
, ở đây mình đặt tên là QuestionAdmin
, sau đó khai báo list có tên là fields
có các item là tên các thuộc tính trong model mà chúng ta muốn hiện ra trong trang Admin, sau đó truyền lớp này vào hàm admin.site.register()
.
Có thể bạn không nhận ra sự thay đổi vì chúng ta trước sau cũng cho hiện ra có 2 thuộc tính, nhưng thực ra khi bạn để Django tự động cho hiện ra hết thì nó sẽ hiển thị các thuộc tính theo thứ tự mà chúng ta khai báo trong file models.py
, còn ở đây Django hiển thị theo thứ tự mà chúng ta khai báo trong biến fields
.
Ngoài ra Django còn cho phép gom nhóm các thuộc tính lại với nhau để hiển thị.
from django.contrib import admin # Register your models here. from .models import Question, Choice class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date']}), ] admin.site.register(Question, QuestionAdmin) admin.site.register(Choice)
Chúng ta khai báo các biến fields
bên trong biến fieldsets
để gom nhóm các thuộc tính lại với nhau. Mỗi nhóm đều có thể có tiêu đề hoặc không có.
Tùy chỉnh model chứa khóa ngoại
Khi bạn vào trang tạo một đối tượng Choice
mới, giao diện hiện ra như hình bên dưới.
Thuộc tính Question
mà chúng ta khai báo là một khóa ngoại tham chiếu đến bảng Question
, trang admin hiện ra một list box để chúng ta chọn các đối tượng Question
có sẵn, ngoài ra bên cạnh còn có một nút dấu + màu xanh lá cây, khi bạn click vào nút này thì một cửa sổ sẽ hiện ra cho bạn tạo một đối tượng Question
mới, sau khi tạo xong thì đối tượng này sẽ được thêm vào list box bên cạnh Question
cho bạn chọn. Nhưng làm thế thì cũng không hay lắm, chúng ta có thể cho phép tạo các đối tượng Choice
ngay khi tạo Question
luôn.
from django.contrib import admin # Register your models here. from .models import Question, Choice class ChoiceInLine(admin.StackedInline): model = Choice extra = 3 class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date']}), ] inlines = [ChoiceInLine] admin.site.register(Question, QuestionAdmin) admin.site.register(Choice)
Chúng ta chỉ cần khai báo một lớp kế thừa từ lớp admin.StackedInLine
, ở đây mình khai báo lớp tên là ChoiceInLine
, sau đó gán thuộc tính model
giá trị là lớp Model mà chúng ta muốn hiện ra (Choice
), thuộc tính extra
cho Django biết có bao nhiêu form nhập vào được hiển thị khi hiển thị bảng cha. Sau đó trong lớp QuestionAdmin
chúng ta khai báo thuộc tính inlines
là lớp ChoiceInLine
mà chúng ta vừa khai báo.
Trong hình trên là giao diện tạo mới một đối tượng Question
với 3 form nhập 3 đối tượng Choice
ngay khi vừa tạo mà chúng ta khai báo trong thuộc tính extra
. Ngoài ra khi bạn vào trang sửa đổi đối tượng có sẵn, chẳng hạn như bạn vào trang sửa đối Question
“What’s up?” với 2 câu trả lời Choice
có sẵn mà chúng ta đã tạo trong suốt series này, Django sẽ tự động hiện 2 đối tượng Choice
đó và hiện ra thêm 3 form Choice #3, Choice #4 và Choice #5 luôn.
Ngoài ra bạn có thể thay đổi kiểu hiển thị các đối tượng khóa ngoại từ dạng danh sách sang dạng bảng.
class ChoiceInLine(admin.TabularInLine): ...
Bạn chỉ cần thay đổi lớp kế thừa từ StackedInLine
sang ChoiceInline
.
Tùy chỉnh trang chỉnh sửa
Hiện tại thì trang chỉnh sửa lớp Question có giao diện như hình dưới.
Mặc định thì Django chỉ để hiển thị đoạn text lấy từ phương thức str()
mà chúng ta đã override trong phương thức __str__()
cho từng đối tượng, chúng ta có thể tùy chỉnh Django hiển thị những thuộc tính khác.
class QuestionAdmin(admin.ModelAdmin): ... list_display = ('question_text', 'pub_date')
Để làm việc này thì chúng ta chỉ cần khai báo danh sách các thuộc tính cần hiển thị ra trong thuộc tính list_display
.
Bạn thậm chí còn có thể sắp xếp các đối tượng Question
bằng cách click chuột vào thanh tiêu đề.
Ngoài ra bạn có thể thêm các ô lọc theo thuộc tính.
class QuestionAdmin(admin.ModelAdmin): ... list_filter = ['pub_date']
Chúng ta khai báo tên các thuộc tính cần lọc trong thuộc tính list_filter
.
Vì thuộc tính pub_date
là kiểu DateTime
nên Django biết cách đưa các tùy chọn vào phần lọc chẳng hạn như Any date, Today… còn đối với các thuộc tính kiểu text hay kiểu số nguyên, số thực thì dường như là không có hiệu quả mấy.
Tiếp theo, chúng ta có thể thêm ô tìm kiếm vào trang admin:
class QuestionAdmin(admin.ModelAdmin): ... search_fields = ['question_text']
Biến search_fields
sẽ hiển thị ô tìm kiếm và chỉ tìm theo thuộc tính mà chúng ta đã khai báo trong đó, bạn cũng có thể thêm các thuộc tính khác vào nhưng nên thêm ít thôi vì Django sử dụng câu truy vấn LIKE với CSDL nên thêm nhiều thuộc tính vào sẽ làm quá trình tìm kiếm chậm đi.
TabularInLine -> TabularInline (chữ L tác giả gõ nhầm thành chữ Capital nha các bạn)
Sửa lại kẻo báo lỗi : AttributeError: ‘module’ object has no attribute ‘TabularInLine’
Mình nhìn lòi mắt mới thấy hic.
sao nó bị lỗi no define hoài