(91) 350-9520 support@omarine.org M-F: 7 AM - 7 PM; Weekends: 9 AM - 5 PM

Lập trình Web: Python: Django: Chương trình thăm dò ý kiến, phần 5

14. Tạo tài khoản admin

python manage.py createsuperuser

Lệnh đó sẽ nhắc bạn vào tên, email, mật khẩu của người sử dụng mà bạn định dùng để login vào trang quản trị

15. Vào trang admin

Bạn chạy server, mở trình duyệt và đi tới http://localhost:8000, rồi nhấn chuột vào Admin trên sidebar (hoặc đi thẳng tới http://localhost:8000/admin/). Màn ảnh login sẽ xuất hiện như sau

Giao diện có thể được trình bày bằng ngôn ngữ khác, như tiếng Việt. Chúng ta sẽ bàn tới dịch ngôn ngữ và ngôn ngữ giao diện sau này. Bây giờ hãy đăng nhập vào trang admin

Mặc định trang admin chỉ có chương trình Xác thực và ủy quyền gồm hai mục soạn thảo được là NhómNgười sử dụng. Chúng được cung cấp bởi django.contrib.auth.

Để thêm chương trình Polls, chúng ta cần đăng ký mô hình của nó. Bạn soạn thảo tệp polls/admin.py với nội dung sau:

from django.contrib import admin

from .models import Question

admin.site.register(Question)

Bây giờ chương trình Polls với mục Câu hỏi đã xuất hiện trên trang đầu admin

Nhấn chuột vào “Questions”. Bạn đã tới trang “Danh sách thay đổi”. Trang này trình bày tất cả các câu hỏi trong cơ sở dữ liệu để bạn chọn lấy một câu hỏi để thay đổi. Chúng ta mới chỉ có một câu hỏi “What’s up?”:

Nhấn chuột vào “What’s up?” để soạn thảo nó:

Những điều cần chú ý ở đây:

  • form được tự động tạo ra từ mô hình Question.

  • Các kiểu trường khác nhau (DateTimeField, CharField) của mô hình tương ứng với các widget đầu vào HTML.

  • Widget kiểu ngày tháng có các shortcut JavaScript: Date nhận một shortcut “Today” và một popup lịch, Time nhận một shortcut “Now” và một popup mà chứa danh sách một số mục thời gian nhập thuận tiện.

Nhấn chuột vào “Today” và “Now” (nếu thời gian không khớp thời gian hiện tại, bạn kiểm tra lại TIME_ZONE và đặt lại cho đúng rồi tải lại trang). Nhấn tiếp “Save and continue editing”, rồi nhấn “HISTORY” ở góc trên bên phải. Bạn sẽ thấy trang nhật ký ghi lại những thay đổi được thực hiện

Bạn có thể sử dụng mysql để thao tác trực tiếp dữ liệu nhật ký này, ví dụ xem hay xóa các bản ghi. Nó nằm trong bảng django_admin_log.

16. Admin: Tùy biến form

Chúng ta đã đăng ký mô hình Question một cách đơn giản. Bây giờ chúng ta xây dựng lớp quản trị mô hình để tạo giao diện thân thiện hơn. Đầu tiên thử sắp xếp lại thứ tự xuất hiện các trường trong trang soạn thảo câu hỏi. Bạn thay đổi tệp polls/admin.py với nội dung mới:

from django.contrib import admin
from .models import Question

class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

Lớp quản trị mô hình QuestionAdmin được định nghĩa và đưa vào đối số thứ hai của hàm register(). Danh sách fields đặt 'pub_date' đằng trước 'question_text' và thứ tự này làm thay đổi giao diện:

Bây giờ chúng ta cho các trường vào các bộ phận riêng để trình bày chúng tách bạch trên màn ảnh:

from django.contrib import admin
from .models import Question

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

fieldsets là một danh sách có 2 tuple tương ứng với mỗi bộ phận trình bày. Mỗi tuple có 2 phần tử, phần tử thứ nhất qui định thanh tiêu đề của bộ phận trình bày, phần tử thứ hai là một từ điển. Chúng ta lần lượt phân tích:

(None, {'fields': ['question_text']})

Bộ phận này không có thanh tiêu đề, từ điển chỉ có 1 khóa, là 'fields', giá trị của nó là một danh sách các xâu kí tự của các tên trường trong bộ phận trình bày, và trong trường hợp này chỉ có 1 trường question_text.

('Date information', {'fields': ['pub_date']})

Bộ phận này có thanh tiêu đề với nhãn là “Date information”, từ điển tương tự như trên, cũng chỉ có 1 trường, là pub_date.

Kết quả là:

Nhận xét:

Định nghĩa lớp QuestionAdmin với

fields = ['question_text', 'pub_date']

là hoàn toàn tương đương với

fieldsets = [
    (None, {'fields': ['question_text', 'pub_date']}),
]

17. Admin: Thêm đối tượng liên quan

Chúng ta đã làm cho đối tượng câu hỏi, bây giờ cần thêm đối tượng bình chọn. Cách đơn giản là đăng ký mô hình Choice với admin.site.register(Choice). Nhưng cách này không tiện vì như thế Choice sẽ thuộc một trang riêng mà liệt kê tất cả các mục bình chọn của tất cả các câu hỏi, trong khi mỗi mục bình chọn chỉ quan hệ với câu hỏi của nó. Khi thêm một mục bình chọn lại cần xác định nó thuộc câu hỏi nào. Giải pháp là nhúng các mục bình chọn vào trang soạn thảo câu hỏi của chúng:

from django.contrib import admin
from .models import Choice, Question

class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]

admin.site.register(Question, QuestionAdmin)

Việc nhúng các mục bình chọn được thực hiện bởi dòng inlines = [ChoiceInline]. Trong đó lớp ChoiceInline lấy mô hình là Choice; extra = 3 xác định mặc định 3 mục bình chọn trống được thêm trước trong trang soạn thảo câu hỏi. Bộ phận ngày xuất bản được thêm lớp collapse, có tác dụng trình bày trong trạng thái co lại để tiết kiệm không gian màn ảnh. Bạn sẽ thấy rõ hơn khi mở trang “Add question”:

Trình bày như thế vẫn còn tốn nhiều diện tích màn ảnh. Chúng ta sửa lớp ChoiceInline, thay lớp cơ sở StackedInline bằng lớp TabularInline, bộ phận CHOICES đã trở nên gọn hơn trong dạng bảng:

18. Admin: Tùy biến danh sách

Mặc định Django chỉ trình bày thuộc tính văn bản của đối tượng trong danh sách

Để trình bày chi tiết các trường của đối tượng dưới dạng các cột, sử dụng tùy chọn list_display. Đó là một tuple các xâu kí tự của tên trường. list_display còn có thể áp dụng cho phương thức của đối tượng như trường hợp đặc biệt. Bạn thêm dòng mã như dưới đây vào lớp quản trị mô hình QuestionAdmin:

class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

Bây giờ trang danh sách câu hỏi đã thay đổi:

Khi bạn nhấn chuột vào một tiêu đề cột, danh sách sẽ được sắp theo cột đó. Riêng trình bày của cột was_published_recently phụ thuộc vào 3 thuộc tính của phương thức was_published_recently() của đối tượng mô hình Câu hỏi. Chúng ta viết lại ở đây:

was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'

Bình thường Django không sắp theo phương thức vì nó chỉ sắp theo các trường của cơ sở dữ liệu. Phép gán cho thuộc tính admin_order_field của phương thức was_published_recently() làm cho cột của nó được sắp như cột pub_date.

Giá trị trả về của phương thức was_published_recently() là boolean. Phép gán cho thuộc tính boolean của nó tới True làm cho các giá trị trong cột được trình bày dạng biểu tượng “on” hoặc “off” thay vì True hoặc False.

Phép gán cho thuộc tính short_description của phương thức was_published_recently() xác định tiêu đề cột của nó. Nếu không có phép gán này, tiêu đề cột được lấy từ tên phương thức với các dấu gạch dưới (_, underscore) được thay bằng kí tự trống.

Tùy chọn list_filter dùng cho tạo lọc trên giao diện. Bạn thêm dòng mã dưới đây vào QuestionAdmin:

list_filter = ['pub_date']

Một sidebar “Filter”để lọc danh sách theo trường pub_date sẽ xuất hiện

Tùy chọn search_fields tạo một hộp tìm kiếm trên đỉnh danh sách, thêm nó vào QuestionAdmin:

search_fields = ['question_text']

Chúng ta có hộp tìm kiếm theo trường question_text

19. Tùy biến diện mạo trang admin

Trang admin mặc định có tiêu đề “Django administration”, tiêu đề đó chẳng thú vị vì nó không đem lại cảm nhận về chương trình Polls. Vì thế chúng ta sẽ đổi tiêu đề thành “Polls administration”. Nhưng không nên sửa đổi mã nguồn Django, vì khi nâng cấp Django lên phiên bản mới nội dung sửa đổi sẽ bị mất. Nguyên tắc chung để tùy biến hay kế thừa một cách an toàn là tạo mới, đặt các đơn vị tài nguyên, mã chương trình mới theo cách chúng được phát hiện trước hoặc viết đè tài nguyên, mã chương trình cũ trong phần tùy biến, kế thừa.

Trong trường hợp này chúng ta sẽ tùy biến khuôn mẫu admin của Django. Chép khuôn mẫu vào dự án rồi sửa đổi bản sao này. Bạn tạo thư mục templates/admin. Chép khuôn mẫu admin/base_site.html trong thư mục khuôn mẫu admin của Django ($HOME/python-env/mysite/lib/python3.6/site-packages/django/contrib/admin/templates) vào thư mục đó.

Soạn thảo base_site.html, thay {{ site_header|default:_('Django administration') }} với Polls administration. Chúng ta có một trang admin với diện mạo mới

Cách tiếp cận trên đây là để chúng ta học tùy biến khuôn mẫu. Nếu chỉ cần thay tiêu đề trang, có thể dùng cách đơn giản hơn, chỉ cần thêm dòng mã dưới đây vào tệp polls/admin.py:

admin.AdminSite.site_header = 'Polls administration'

20. Admin: Tùy biến trang đầu

Khuôn mẫu trang đầu là admin/index.html, cách xử lý tương tự như admin/base_site.html, chép nó từ thư mục khuôn mẫu Django vào thư mục khuôn mẫu dự án. index.html có một biến khuôn mẫu là app_list. Biến này chứa tất cả các chương trình trong INSTALLED_APPS mà đã đăng ký với chương trình admin, xếp theo thứ tự bảng chữ cái. index.html lặp qua biến này để trình bày các chương trình.

mysite có hai chương trình trong admin, trong đó chương trình Xác thực và ủy quyền ở trên chương trình Polls. Chúng ta làm một ví dụ tùy biến đơn giản: xếp chương trình Polls lên trên. Bạn soạn thảo index.html, thay dòng mã {% for app in app_list %} với

{% for app in app_list reversed %}

Kết quả là:

Sử dụng biến app_list có thuận lợi là tận dụng thuộc tính và truy cập mô hình chương trình. Bạn cũng có thể viết mã nối tới các trang quản trị gắn với đối tượng cụ thể tùy theo sở thích.

Advertisements

Gửi phản hồi

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.

%d bloggers like this: