You are on page 1of 69

Django

• Khóa học cấp tốc Python (ERIC MATTHES)


Nội dung
• Bắt đầu với Django
• Tài khoản người dùng
• Tạo kiểu và triển khai ứng dụng
1. Bắt đầu với Django
1.1. Thiết lập dự án
1.2. Bắt đầu một ứng dụng
1.3. Tạo trang: Trang chủ
1.4. Xây dựng các trang bổ sung
2. Tài khoản người dùng
2.1. Cho phép người dùng nhập dữ liệu
2.2. Thiết lập tài khoản người dùng
2.3. Cho phép người dùng sở hữu dữ liệu của
họ
2.1. Cho phép người dùng đến Nhập dữ liệu
• Trước khi xây dựng hệ thống xác thực để tạo tài khoản, trước tiên
chúng tôi sẽ thêm một số trang cho phép người dùng nhập dữ liệu của
riêng họ.
• Chúng tôi sẽ cung cấp cho người dùng khả năng thêm chủ đề mới,
thêm mục nhập mới và chỉnh sửa các mục nhập trước đó của họ.
• Hiện tại, chỉ siêu người dùng mới có thể nhập dữ liệu thông qua trang
web quản trị. Chúng tôi không muốn người dùng tương tác với trang
web quản trị, vì vậy chúng tôi sẽ sử dụng các công cụ xây dựng biểu
mẫu của Django để xây dựng các trang cho phép người dùng nhập dữ
liệu.
• Thêm chủ đề mới
2.1. Cho phép người dùng đến Nhập dữ liệu
• Hãy bắt đầu bằng cách cho phép người dùng thêm một chủ đề mới.
• Thêm một trang dựa trên biểu mẫu hoạt động theo cách tương tự như
các trang chúng tôi đã xâydựng: chúng tôi xác định URL, viết hàm
xem và viết mẫu.
• Một sự khác biệt lớn là việc bổ sung một mô-đun mới gọi là forms.py,
sẽ chứa các biểu mẫu.
• Thêm chủ đề mới - Chủ đề ModelForm
• Bất kỳ trang nào cho phép người dùng nhập và gửithông tin rmation
trên một trang web là một biểu mẫu, ngay cả khi nó không giống như
một biểu mẫu.
2.1. Cho phép người dùng đến Nhập dữ liệu
• Khi người dùng nhập thông tin, chúng tôi cần xác thực rằng thông tin
được cung cấp là đúng loại dữ liệu và không độc hại, chẳng hạn như
mã để làm gián đoạn máy chủ của chúng tôi.
• Sau đó, chúng tôi cần xử lý và lưu thông tin hợp lệ vào vị trí thích hợp
trong cơ sở dữ liệu. Django tự động hóa phần lớn công việc này.
• Thêm chủ đề mới - Chủ đề ModelForm
• Cách đơn giản nhất để xây dựng một biểu mẫu trong Django là sử
dụng ModelForm, sử dụng thông tin từ các mô hình to tự động xây
dựng một biểu mẫu.
• Viết biểu mẫu đầu tiên của bạn trong forms.py tệp mà bạn nên tạo
trong cùng thư mục với models.py:
2.1. Cho phép người dùng đến Nhập dữ liệu

forms.py từ django nhập biểu mẫu từ .models

import Topic

O class TopicForm(forms. Chế độ 1Form) :


lớp Meta:
mẫu

• Thêm chủ đề mới - URL new_topic


• URL cho một trang mới phải ngắn gọn và mô tả.
• Khi người dùng muốn thêm một chủ đề mới, chúng tôi sẽ gửi chúng
đến http:///oca/host:8000/new_topic/.
2.1. Cho phép người dùng đến Nhập dữ liệu
• Dưới đây là mẫu URL cho trang new_topic mà bạn thêm vào
learning_logs/url.py:

urls.py --smp-urlpattern

• -Snip--
# Trang để thêm đường dẫn chủ đề mới
( new_topic / ', views.new_topic,

• Thêm chủ đề mới - Hàm new_topic() View


• Hàm new_topic() cần xử lý hai tình huống khác nhau: yêu cầu ban
đầu cho trang new_topic (trong trường hợp đó nó sẽ hiển thị một biểu
mẫu trống) và xử lý bất kỳ dữ liệu nào được gửi trong biểu mẫu.
2.1. Cho phép người dùng đến Nhập dữ liệu
• Sau khi dữ liệu từ một biểu mẫu đã gửi được xử lý, nó cần phải
redirect người dùng trở lại trang chủ đề:
• Thêm chủ đề mới - Hàm new_topic() View

views.py từ Django. phím tắt nhập kết xuất, chuyển hướng

từ. mô hình nhập Chủ đề từ .


nhập biểu mẫu TopicForm
- snip-def chủ đề mới
(yêu cầu):
"""Thêm chủ đề mới. "" " o if
request.method 'POST':
# Không có dữ liệu nào được gửi; Tạo một biểu
mẫu trống. hình thức TopicForm()
2.1. Cho phép người dùng đến Nhập dữ liệu
# POST dữ liệu đã gửi; xử lý dữ liệu. form = if form.
is_valid(): form. save() return

redirect( '
# Hiển thị một biểu mẫu trống hoặc không hợp lệ. e context =
, ' html ', context)
{'form': form} return render (request

• Thêm chủ đề mới - Yêu cầu GET và POST


• Hai loại yêu cầu chính bạn sẽ sử dụng khi xây dựng ứng dụng web là
yêu cầu GET và yêu cầu POST.
• Bạn sử dụng yêu cầu GET cho các trang chỉ đọc dữ liệu từserv er.
• Bạn thường sử dụng yêu cầu POST khi người dùng cần gửi thông tin
qua biểu mẫu.
• Thêm chủ đề mới - Mẫu new_topic
2.1. Cho phép người dùng đến Nhập dữ liệu
• Bây giờ chúng ta sẽ tạo một template mới gọi là new_topic.html để
hiển thị form mà chúng ta vừa tạo

new_topic.html {X mở rộng "learning_logs/base. html" X}


{X chặn nội dung X}
Một chủ đề mới:

• (url mẫu 'learning_logs: new_topic• Z}" phương thức-'post'> O {X csrf token X} O {f form. as_p o (button name:"

< / biểu mẫu


{X endblock content X}
2.1. Cho phép người dùng đến Nhập dữ liệu
• Thêm chủ đề mới - Liên kết đến trang new_topic
• Tiếp theo, chúng tôi bao gồm một liên kết đến trang new_topic
trên trang chủ đề:

chủ đề.html
2.1. Cho phép người dùng đến Nhập dữ liệu
• Thêm mục nhập mới - Mục nhập ModelForm
• Chúng ta cần tạo một biểu mẫu được liên kết với mô hình Entry
nhưng lần này với một chút tùy chỉnh hơn TopicForm:
forms.py từ django nhập biểu mẫu từ -models
import Chủ đề, Mục nhập
lớp TopicForm(biểu mẫu. Chế độ 1Form) :
--SNLP--
lớp EntryForm(forms. Mode1Form) :
class Meta: model = Entry fields - - [ '

text ' ] labels - - { 'text': 'Entry:

• widgets = {'văn bản' : biểu mẫu. "Ừm.

• Thêm mục nhập mới - URL new_entry


2.1. Cho phép người dùng đến Nhập dữ liệu
• Các mục nhập mới phải được liên kết với một chủ đề cụ thể, vì
vậy chúng ta cần bao gồm một đối số topic_id trong URL để thêm
một mục nhập mới. Dưới đây là URL mà bạn thêm vào
learning_logs/url.py:

urls.py --snip-urlpattern =
--Snip--
# Trang để thêm đường dẫn mục nhập mới ( ' new_entry / <int:
topic_id> / ', lượt xem. new_entry, name = ' mục nhập mới' ) ,

• Thêm các mục nhập mới - hàm xem new_entry()


2.1. Cho phép người dùng đến Nhập dữ liệu
• Chức năng xem cho new_entry giống như chức năng để thêm một
chủ đề mới. Thêm mã sau vào tệp views.py của bạn:

từ. maels nhập Chủ đề

Fore Biểu mẫu


nhập cảnh() khác:
# POST dữ liệu gửi; xử lý dữ liệu.
new_entry • trước. lưu (comit•FaIse) new_entry.topic chủ đề
new_entry. save() return

# Hiển thị ngữ cảnh biểu mẫu trống hoặc


không hợp lệ z { • chủ đề': chủ đề, • biểu
mẫu': biểu mẫu)
2.1. Cho phép người dùng đến Nhập dữ liệu

• Thêm mục mới - Mẫu new_entry


• Như bạn có thể thấy trong đoạn mã sau, mẫu cho new_entry
tương tự như mẫu cho new_topic:

new_entry.html {X mở rộng "learning_logs/base. html" X}


{X chặn nội dung Z}

new_entry' topic.id X}"


topic.id chủ đề
(tên nút-' gửi' >Thêm mục nhập< / nút> < /
biểu mẫu)
2.1. Cho phép người dùng đến Nhập dữ liệu
{X endblock content X}

• Thêm mục mới - Liên kết đến trang new_entry


• Tiếp theo, chúng ta cần bao gồm một liên kết đến trang new_entry
từ mỗi trang chủ đề trong mẫu chủ đề:

topic.html {X mở rộng "learning_logs/base.html " Z}


2.1. Cho phép người dùng đến Nhập dữ liệu

{X chặn url nội dung ' learning_logs: new_entry'


topic.id mới
{X endblock content X}

• Thêm mục nhập mới


• Giờ đây, người dùng có thể thêm chủ đề mới và bao nhiêu mục tùy
thích cho mỗi chủ đề. Hãy thử trang new_entry bằng cách thêm
một vài mục nhập vào một số chủ đề bạn đã tạo.
2.1. Cho phép người dùng đến Nhập dữ liệu

• Chỉnh sửa mục nhập - URL edit_entry


• URL cho trang cần phải vượt qua ID của mục nhập cần chỉnh sửa.
Đây là learning_logs/url.py:
2.1. Cho phép người dùng đến Nhập dữ liệu
urls.py --snäp-urlpattern

--Snip--
# Trang để chỉnh sửa một mục.
path( ' edit_entry/ <int : entry_id>/ ' , lượt xem. edit_entry, tên:' edit_entry') ,

• Chỉnh sửa mục nhập - Hàm xem edit_entry()


• Khi trang edit_entry nhận được yêu cầu GET, hàm edit_entry() trả
về biểu mẫu để chỉnh sửa mục nhập.
• Khi trang ghilại yêu cầu POST với văn bản mục nhập đã sửa đổi,
nó sẽ lưu văn bản đã sửa đổi vào cơ sở dữ liệu:
2.1. Cho phép người dùng đến Nhập dữ liệu
• Chỉnh sửa mục nhập - Hàm xem edit_entry()

views-py từ Django. phím tắt nhập kết xuất, chuyển hướng


từ .models import Topic, Entry from . biểu
mẫu nhập TopicForm, EntryForm - -snip--

def edit_entry(yêu cầu, entry_id):


"""Chỉnh sửa mục nhập hiện có."" n
O entry Entry.objects topic
entry. chủ đề
if request.method ' POST':
# Yêu cầu ban đầu; điền sẵn biểu mẫu với mục nhập hiện
tại. form = EntryForm (instance-entry) else •
# POST dữ liệu đã gửi; xử lý dữ liệu.

• dữ liệu biểu mẫu—yêu cầu. POST) nếu form.is_valid(): biểu mẫu. save() return redirect(
topic_id=topic.id)
2.1. Cho phép người dùng đến Nhập dữ liệu
context {'entry': entry, 'topic': topic, 'form': form} return render
(request, html', context)

• Chỉnh sửa mục nhập - Mẫu edit_entry


• Tiếp theo, chúng tôi tạo một mẫu edit_entry.html, tương tự như
new_entry.html:
edit_entry.html {X Kéo dài "learning_logs/căn cứ.
HTML
"
{X chặn nội dung X} href="{% URL 'learning_logs:topic' topic.id
mục nhập chủ đề:

• ( url mẫu 'learning_logs:edit_entry' entry.id Z}" method-' post' >


{X csrf_token form.as_p o (nút

</biểu mẫu
{X endblock content X}
2.1. Cho phép người dùng đến Nhập dữ liệu

• Chỉnh sửa mục nhập - Liên kết đến trang edit_entry


• Bây giờ chúng ta cần bao gồm một liên kết đến trang edit_entry
cho mỗi mục trên trang chủ đề:

Chủ đề.html- - Snip-


{Z để nhập vào mục X}
mục.
date_addedldate:
Mục 'M d, Y H:i'.
URL ngắt

dòng văn bản '


learning_logs:edit_entry' entry.id mục</a>
2.1. Cho phép người dùng đến Nhập dữ liệu
--Snip--
2.1. Cho phép người dùng Nhập dữ liệu
đến
• Chỉnh sửa mục nhập

TKVk:

• Tháng Hai 19.201907T

Emwgh
Euty
2.2. Khung cảnh Lên người dùng Tài khoản

• Trong phần này, chúng tôi sẽ thiết lập hệ thống đăng ký và ủy


quyền người dùng để mọi người có thể đăng ký tài khoản và đăng
nhập và đăng xuất.
• Chúng tôi sẽ tạo một ứng dụng mới để chứa tất cả các chức năng
liên quan đến làm việc với người dùng.
• Chúng tôi sẽ sử dụng hệ thống xác thực người dùng mặc định đi
kèm với Django để thực hiện càng nhiều công việc càng tốt.
2.2. Khung cảnh Lên người dùng Tài khoản
• Chúng tôi cũng sẽ sửa đổi mô hình Chủ đề một chút để mọi chủ đề
thuộc về một người dùng nhất định.
• Ứng dụng người dùng
• Chúng ta sẽ bắt đầu bằng cách tạo một ứng dụng mới có tên users,
sử dụng lệnh startapp:

(Il_env)learning_log$ Người dùng Python manage.py StartApp



O db. sq1ite3 learning_log learning_logs ll_env quản lý. Người dùng
py Là người dùng
O init_.py admin.py ứng dụng.py mô hình di chuyển.py thử nghiệm.py dạng xem.py
2.2. Khung cảnh Lên người dùng Tài khoản
• Ứng dụng người dùng - Thêm người dùng vào settings.py
• Chúng tôi cần thêm ứng dụng mới của mình vào ỨNG DỤNG ĐÃ
CÀI ĐẶT trong settings.py

settings.py --Bắn tỉa--


ỨNG DỤNG ĐÃ CÀI ĐẶT
# Ứng dụng của tôi
'learning_logs ',
' người dùng ' ,
# Ứng dụng django mặc định.
--Snip--
--Snip--

• Ứng dụng người dùng - Bao gồm URL từ người dùng


2.2. Khung cảnh Lên người dùng Tài khoản
• Tiếp theo, chúng ta cần sửa đổi urls.py gốc để nó bao gồm các URL
chúng ta sẽ viết cho ứng dụng users:

urls.py từ Django. Đóng góp nhập quản trị viên từ


Django. Đường dẫn nhập URL, bao
gồm

urlpatterns = path( ' admin/ ',


admin. site. urls), path( '
users/' , include( ' users.urls ') ),
path(", include( ' learning_logs. urls ') ,
,

• Trang đăng nhập


2.2. Khung cảnh Lên người dùng Tài khoản
• Trước tiên, chúng tôi sẽ triển khai trang đăng nhập. Chúng tôi sẽ sử
dụng chế độ xem đăng nhập mặc định mà Django cung cấp, vì vậy
mẫu URL cho ứng dụng này trông hơi khác một chút. Tạo một tệp
urls.py mới trong thư mục learning_log/users/, và thêm nội dung
sau vào đó:
urls.py "
"Xác định mẫu URL cho người dùng"
từ django. Đường dẫn nhập URL, bao
gồm
O tên ứng dụng = ' người dùng '
urlpatterns =
# Bao gồm url xác thực mặc định.
• path( ", include( ' django. đóng góp. auth. urls '
• Trang đăng nhập - Mẫu đăng nhập
2.2. Khung cảnh Lên người dùng Tài khoản
• Khi người dùng request trang đăng nhập, Django sẽ sử dụng chức
năng view mặc định, tuy nhiên chúng ta vẫn cần cung cấp template
cho trang.
• Các chế độ xem xác thực mặc định tìm kiếm các mẫu bên trong
một thư mục được gọi là đăng ký, vì vậy chúng ta sẽ cần tạo thư
mục đó.
• Bên trong thư mục learning_log/users/, tạo một thư mục có tên
templates; Bên trong đó, tạo một thư mục khác gọi làRegist Ration.
• Trang đăng nhập - Mẫu đăng nhập
• Đây là mẫu đăng nhập.html mà bạn nên lưu trong
learning_log/users/templates/registration:
login.html {Z mở rộng "learning_logs/base. HTML"
{Z chặn nội dung X}
2.2. Khung cảnh Lên người dùng Tài khoản
• {X nếu form.errors X} Tên người dùng và mật khẩu không khớp. Vui lòng thử lại.</p>
{X endif X}

• (form method="post" url 'users:login' {% csrf_token X} o form.as_p } }

Nút O<
< liệu

< /mẫu>

{X endblock content X}

• Trang đăng nhập - Liên kết đến trang đăng nhập


• Hãy thêm liên kết đăng nhập vào cơ sở.html để nó xuất hiện trên mọi
trang.
• Chúng tôi không muốn liên kết hiển thị khi người dùng đã đăng nhập,
vì vậy chúng tôi lồng nó vào bên trong thẻ {% if %}:
căn cứ.html
2.2. Khung
h
cảnh Lên người dùng Tài khoản
e
o

c
hoặc
{X endif X}

• Trang đăng nhập - Sử dụng trang đăng nhập


• Chúng tôi đã thiết lập tài khoản người dùng, vì vậy hãy đăng nhập
để xem trang có hoạt động không.
• Đi tới http:///oca/host:8000/admin/. Nếu bạn vẫn đăng nhập với tư
cách quản trị viên, hãy tìm liên kết đăng xuất trong tiêu đề và nhấp
vào liên kết đó.
2.2. Khung cảnh Lên người dùng Tài khoản
• Trang đăng nhập - Sử dụng trang đăng nhập
• Khi bạn đã đăng xuất, hãy truy cập http://localhost:8000/users/login/.
• Bạn sẽ thấy một trang đăng nhập.
• Nhập tên người dùng và mật khẩu bạn đã thiết lập trước đó và bạn sẽ
được đưa trở lại trang chỉ mục.
• Tiêu đề trên trang chủ sẽ hiển thị lời chào được cá nhân hóa với tên
người dùng của bạn.
• Trang đăng nhập

Người dùng:

trong
2.2. Khung cảnh Lên người dùng Tài khoản
• Đăng xuất - Thêm liên kết đăng xuất vào cơ sở.html
• Chúng tôi sẽ thêm liên kết để đăng xuất vào cơ sở.html vì vậy nó có
sẵn trên mọi trang.
• Chúng tôi sẽ bao gồm nó trong phần {% nếu user.is_authenticated %}
để chỉ những người dùng đã đăng nhập mới có thể xem nó:

Căn cứ.html- -Cắt—

{% nếu người dùng. được xác thực %}


_
Xin chào, { { user. tên người dùng
( UR1 'Người dùng: Đăng xuất' < / A>
{% khác 0/0}
--Snip--
2.2. Khung cảnh Lên người dùng Tài khoản
• Đăng xuất - Trang xác nhận đăng xuất
• Người dùng sẽ muốn biết rằng họ đã đăng xuất thành công, vì vậy chế
độ xem đăng xuất mặc định sẽ hiển thị trang bằng cách sử dụng
logged_out.html mẫu mà chúng ta sẽ tạo ngay bây giờ.
• Đây là một trang đơn giản xác nhận rằng người dùng đã đăng xuất.
• Lưu tệp này trong các mẫu / đăng ký, cùng một nơi mà bạn đã lưu
thông tin đăng nhập.html:

logged_out.html {X mở rộng "learning_logs/base. html" X}


{X chặn nội dung X} đã được đăngxuất. Cảm ơn bạn
đã ghé thăm!</p>
{X endblock content

• Đăng xuất
2.2. Khung cảnh Lên người dùng Tài khoản
• Hình dưới đây cho thấy trang đã đăng xuất như nó xuất hiện cho
người dùng vừa nhấp vào liên kết Đăng xuất.

• Trang đăng ký
• Tiếp theo, chúng tôi sẽ xây dựng một trang để người dùng mới có thể
đăng ký.
2.2. Khung cảnh Lên người dùng Tài khoản
• Chúng ta sẽ sử dụng UserCreationForm mặc định của Django nhưng
viết hàm view và template của riêng chúng ta.
• Trang đăng ký— URL đăng ký
• Đoạn mã sau đây cung cấp mẫu URL cho trang đăng ký, một lần nữa
trong người dùng / url.py:

urls.py """"Defines URL patterns for users""" từ


django. Đường dẫn nhập URL, bao gồm
từ . Nhập dạng xem
app_name = ' urlpattern

người dùng
# Bao gồm url xác thực mặc định.
path(", include( ' django. contrib.auth.urls')), #
Trang đăng ký.
path(' register/', views.register, name-'register'),
2.2. Khung cảnh Lên người dùng Tài khoản
• Trang đăng ký - hàm register() View
• Hàm view register() cần hiển thị một biểu mẫu đăng ký trống khi
trang đăng ký được yêu cầu lần đầu tiên và sau đó xử lý các biểu mẫu
đăng ký đã hoàn thành khi chúng được gửi.
• Khi đăng ký thành công, chức năng cũng cần đăng nhập người dùng
mới.
• Thêm mã sau vào người dùng/chế độ xem.py
• Trang đăng ký - hàm register() View

ViewSpy từ Django. phím tắt import render, redirect from django. con
trib. auth nhậpđăng nhập từ django. đóng góp. auth. biểu
mẫu nhập khẩu UserCreationForm
2.2. Khung cảnh Lên người dùng Tài khoản
def register (yêu cầu): i'"
"Đăng ký người
dùng mới.
if request.method ' POST':
# Hiển thị mẫu đăng ký trống. form =
UserCreationForm() else:

# Quy trình biểu mẫu đã hoàn


thành.
form = UserCreationForm(datazrequest. BÀI)

o nếu hình thức. is_valid(): người dùng mới = form.save()


# Đăng nhập người dùng và sau đó chuyển hướng đến trang chủ.
login(request, new_user) return
redirect(' learning_logs:index')
# Hiển thị một biểu mẫu trống hoặc không hợp lệ. context
{'form': form} return render(request, 'registration/register.html'
, context)

o Trang đăng ký - Mẫu đăng ký


2.2. Khung cảnh Lên người dùng Tài khoản
o Bây giờ hãy tạo một mẫu cho trang đăng ký, sẽ tương tự như trang
đăng nhập. Hãy chắc chắn lưu nó trong cùng một thư mục với
Đăng nhập.html:
đăng ký.html

{X mở rộng "learning_logs/base.html" X}
{X chặn nội dung X}

Địa
chỉ

Địa chỉ X}" />


{X endblock content Z}
2.2. Khung cảnh Lên người dùng Tài khoản
• Trang đăng ký - liên kết đến trang đăng ký
• Tiếp theo, chúng tôi sẽ thêm mã để hiển thị liên kết trang đăng ký cho
bất kỳ người dùng nào hiện chưa đăng nhập:

căn cứ. html- -cắt--


{% nếu người dùng. is_authenticated X}
Xin chào, {{ user. tên người dùng
<a href="{% URL 'users:logout' else
<a href="{% url 'users:register' < a url ' users:
login' %}">Log in</a> endif
• -Snip--
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Người dùng sẽ có thể nhập dữ liệu dành riêng cho họ, vì vậy chúng tôi
sẽ tạo một hệ thống để tìm ra dữ liệu nào thuộc về người dùng nào.
• Sau đó, chúng tôi sẽ hạn chế quyền truy cập vào một số trang nhất
định để người dùng chỉ có thể làm việc với dữ liệu của riêng họ.
Chúng tôi sẽ sửa đổi mô hình Chủ đề để mọi chủ đề thuộc về một
người dùng cụ thể.
• Điều này cũng sẽ chăm sóc các mục, bởi vì mỗi mục thuộc về một chủ
đề cụ thể. Chúng ta sẽ bắt đầu bằng cách giới hạn access ở một số
trang nhất định.
• Hạn chế quyền truy cập với @login_required
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Django giúp dễ dàng hạn chế quyền truy cập vào một số trang nhất
định đối với người dùng đã đăng nhập thông qua trình trang trí
@login_required.
• Trình trang trí là một chỉ thị được đặt ngay trước định nghĩa hàm mà
Python áp dụng cho hàm trước khi nó chạy, để thay đổi cách mã hàm
hoạt động.
• Hạn chế quyền truy cập với @login_required
• Hạn chế quyền truy cập vào trang Chủ đề:
• Mỗi chủ đề sẽ thuộc sở hữu của một người dùng, vì vậy chỉ những
người dùng đã đăng ký mới có thể yêu cầu trang chủ đề. Thêmmã sau
vào learning_logs/views.py:
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
views.py từ Django. phím tắt import render, redirect from
django.contrib.auth.decorators import login_required

từ. mô hình nhập Chủ đề, Mục nhập --snip--

@login_required def
topics(request):

"""Hiển thị tất cả các


chủ đề.
--Snip--

• Hạn chế quyền truy cập với @login_required


2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Mã trong login_required() kiểm tra xem người dùng có đăng nhập hay
không và Django chỉ chạy mã trong topics() nếu có.
• Nếu người dùng chưa đăng nhập, họ sẽ được chuyển hướng đến trang
đăng nhập .
• Để làm cho chuyển hướng này hoạt động, chúng ta cần sửa đổi
settings.py để Django biết nơi tìm trang đăng nhập. Thêm nội dung
sau vào cuối settings.py:

settings.py --snjp--

# Cài đặt của tôi


URL ĐĂNG NHẬP người dùng: đăng nhập'
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Hạn chế quyền truy cập với@logi n_required
• Hạn chế quyền truy cập trong suốt nhật ký học tập
• Django giúp bạn dễ dàng hạn chế quyền truy cập vào các trang, nhưng
bạn phải quyết định trang nào cần bảo vệ.
• Tốt nhất là suy nghĩ về những trang nào cần được không hạn chế
trước tiên, và sau đó hạn chế tất cả các trang khác trong dự án. Bạn có
thể dễ dàng sửa lỗi truy cập quá hạn chế và ít nguy hiểm hơn so với
việc để các trang nhạy cảm không bị hạn chế.
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Trong Nhật ký học tập, chúng tôi sẽ giữ trang chủ và trang đăng ký
không bị hạn chế. Chúng tôi sẽ hạn chế quyền truy cập vào mọi trang
khác.
• Hạn chế quyền truy cập với @login_required
• Hạn chế quyền truy cập trong suốt nhật ký học tập
• Dưới đây là learning_logs/views.py với @login_required trình trang
trí được áp dụng cho mọi chế độ xem ngoại trừ index():
def topics(request):
--SNLP--

def topic(yêu cầu, topic_id):


--SNLP--
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu Slogin_required
def
--Snip--

• Kết nối dữ liệu với một số người dùng nhất định


• Tiếp theo, chúng ta cần kết nối dữ liệu với người dùng đã gửi nó.
• Chúng ta chỉ cần kết nối dữ liệu cao nhất trong hệ thống phân cấp với
người dùng và dữ liệu cấp thấp hơn sẽ theo sau.
• Ví dụ: trong Nhật ký học tập, chủ đề là mức dữ liệu cao nhất trong ứng
dụng và tất cả các mục nhập đều được kết nối với một chủ đề.
• Miễn là mỗi chủ đề thuộc về một người dùng cụ thể, chúng tôi có thể
theo dõi quyền sở hữu của từng mục nhập trong cơ sở dữ liệu.
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Chúng ta sẽ sửa đổi mô hình Chủ đề bằng cách thêm mối quan hệ khóa
ngoại cho người dùng. Sau đó, chúng ta sẽ phải di chuyển cơ sở dữ liệu.
Cuối cùng, chúng tôi Il sửa đổi một số chế độ xem để chúng chỉ hiển thị
dữ liệu được liên kết với người dùng hiện đang đăng nhập.
• Kết nối dữ liệu với một số người dùng nhất định
• Sửa đổi Chế độ Chủ đề l:Việc sửa đổi thành models.py chỉ là hai
dòng:

models." từ django.db nhập mô hình từ


django.contrib.auth.models nhập User

lớp Chủ đề (mô hình. Chế độ 1):


"""Một chủ đề mà người dùng đang tìm
hiểu. văn bản = mô hình. ngày Thêm
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
CASCADE)

Def

"Trả về một biểu diễn chuỗi của mô hình. Trở về bản


thân. văn bản
class Entry(models.model):
--SNFP--
• Kết nối dữ liệu với một số người dùng nhất định
• Xác định người dùng hiện tại
• Khi chúng ta di chuyển cơ sở dữ liệu, Django sẽ sửa đổi cơ sở dữ liệu
để nó có thể lưu trữ kết nối giữa từng chủ đề và người dùng.
• Để thực hiện di chuyển, Django cần biết người dùng nào cần liên kết
với từng chủ đề hiện có.
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Cách tiếp cận đơn giản nhất là bắt đầu bằng cách cung cấp tất cả các
chủ đề hiện có cho một người dùng — ví dụ: siêu người dùng. Nhưng
trước tiên chúng ta cần biết ID của người dùng đó.
• Kết nối dữ liệu với một số người dùng nhất định
• Xác định người dùng hiện tại: Hãy xem ID của tất cả người dùng
được tạo cho đến nay. Bắt đầu phiên Django shell và đưa ra các lệnh
sau:

(ll_env)learning_log$ Python manage.py shell


O từ django.contrib.auth.models nhập User
o User.objects.all()
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
<QuerySet [<User: 11 admin), (User: eriC>, <User:
willie>]> O cho user trong User.objects.all():
print(người dùng. tên người dùng, user.id)
11 quản trị
viên Tôi eric
2 willie 3

• Kết nối dữ liệu với một số người dùng nhất định


• Di chuyển cơ sở dữ liệu
• Bây giờ chúng ta đã biết các ID, chúng ta có thể di chuyển cơ sở dữ
liệu.
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Khi chúng tôi thực hiện việc này, Python sẽ yêu cầu chúng tôi tạm
thời kết nối mô hình Chủ đề với một chủ sở hữu cụ thể hoặc thêm mặc
định vào tệp models.py của chúng tôi để cho nó biết phải làm gì.
Chọn tùy chọn 1:
• Kết nối dữ liệu với một số người dùng nhất định
• Di chuyển cơ sở dữ liệu
Python manage.py makemigrations learning_logs

Bạn đang cố gắng thêm một 'chủ sở hữu' trường không nullable vào chủ đề mà

không có mặc định; Chúng tôi không thể làm điều đó (cơ sở dữ liệu cần một cái
gì đó để điền vào các hàng hiện có). O Vui lòng chọn bản sửa lỗi:
1) Cung cấp mặc định một lần ngay bây giờ (sẽ được đặt trên tất cả các hàng hiện
có với giá trị null cho cột này)
2) Thoát và để tôi thêm mặc định trong các mô hình. .py
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
o Chọn một tùy chọn: 1
O Vui lòng nhập giá trị mặc định ngay bây giờ, là Python hợp lệ
Datetime và django.utils. Các mô-đun múi giờ có sẵn, vì vậy bạn có thể làm
ví dụ: timezone.now
Nhập 'thoát' để thoát khỏi lời nhắc này
Di chuyển cho 'learning_logs ':
learni ng_logs/migrations py

• Chủsở hữu trường dd cho chủ đề


(ll_env) learning_log$

• Kết nối dữ liệu với một số người dùng nhất định


• Di chuyển cơ sở dữ liệu: Bây giờ chúng ta có thể thực hiện di chuyển.
Nhập thông tin sau vào môi trường ảo đang hoạt động:
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
Các thao tác cần thực hiện:
Áp dụng tất cả các di chuyển: admin, auth, contenttypes, learning_logs,
sessions Chạy di chuyển:
Áp dụng learning_logs. 0003_topic_owner. . . OK
(ll_env) learning_log$

• Kết nối dữ liệu với một số người dùng nhất định


• Di chuyển cơ sở dữ liệu: Chúng tôi có thể xác minh rằng việc di
chuyển hoạt động như mong đợi trong phiên shell, như thế này:
O từ learning_logs.models nhập Chủ đề O cho
chủ đề trong Chủ đề. Đối tượng. all(): print
(chủ đề, chủ đề. chủ sở hữu)

Cờ vua 11 admin
Leo núi Il_admin
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Hạn chế quyền truy cập chủ đề đối với người dùng thích hợp
• Hiện tại, nếu bạn đã đăng nhập, bạn sẽ có thể xem tất cả các chủ đề,
bất kể bạn đăng nhập với tư cách là người dùng nào.
• Chúng tôi sẽ thay đổi điều đó bằng cách chỉ hiển thị cho người dùng
các chủ đề thuộc về họ.
• Thực hiện thay đổi sau đối với hàm topics() trong views.py:

views.py --Bắn tỉa--

Chủ đề def (yêu cầu):


2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
'Hiển thị tất cả các chủ đề. """ topics = Chủ đề. Đối tượng. ngày thêm

vào' ) ngữ cảnh - - {'chủ đề': chủ đề}


trả về kết xuất (yêu cầu, • learning_logs/chủ đề.html , ngữ cảnh)
--Cắt—

• Hạn chế quyền truy cập chủ đề đối với người dùng thích hợp
• Khi người dùng đăng nhập, đối tượng request có bộ thuộc tính
request.user lưu trữ thông tin về người dùng.
• Truy vấn Topic.objects.filter(owner=request.user) yêu cầu Django chỉ
truy xuất các đối tượng Topic từ cơ sở dữ liệu có thuộc tính owner
khớp với người dùng hiện tại.
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Vì chúng tôi không thay đổi cách hiển thị chủ đề, chúng tôi hoàn toàn
không cần thay đổi mẫu cho trang chủ đề.
• Bảo vệ chủ đề của người dùng
• Chúng tôi chưa hạn chế quyền truy cập vào các trang chủ đề, vì vậy
bất kỳ người dùng đã đăng ký nào cũng có thể thử một loạt các URL,
như http:///oca/host:8000/topics/1/ và truy xuất các trang chủ đề trùng
khớp.
• Hãy tự mình thử:
• Trong khi đăng nhập với tư cách là người dùng sở hữu tất cả các chủ đề, hãy
sao chép URL hoặc ghi chú ID trong URL của một chủ đề, sau đó đăng xuất
và đăng nhập lại với tư cách là người dùng khác.
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Enter URL của chủ đề đó. Bạn sẽ có thể đọc các mục, ngay cả khi bạn đã đăng
nhập với tư cách là người dùng khác.
• Bảo vệ chủ đề của người dùng
• Chúng ta sẽ khắc phục điều này ngay bây giờ bằng cách thực hiện
kiểm tra trước khi truy xuất các mục được yêu cầu trong hàm xem
topic():

Wews. PY từ Django. phím tắt import render, redirect from django.


contrib.auth. trang trí nhập khẩu login_required
O từ django.http nhập khẩu Http404

• -Snip--
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
def topic(yêu cầu, topic_id):
"""Hiển thị một chủ đề duy nhất và tất cả các
mục của nó. """ chủ đề Chủ đề. objects.get(id-
topic_id)
# Đảm bảo chủ đề thuộc về người dùng hiện tại. o
nếu chủ đề. Yêu cầu của chủ sở hữu. người dùng: nâng
cao Http404

entries topic.entry_set.order_by( • -date_added' ) context --


{'topic': topic, 'entries': entries) return render(request, '
learning_logs/topic .html' , context)
--SNLP--

• Bảo vệ chủ đề của người dùng


• Phản hồi 404 là phản hồi lỗi tiêu chuẩn được trả về khi tài nguyên được
yêu cầu không tồn tại trên máy chủ.
• Ở đây chúng tôi nhập ngoại lệ Http404 (1), mà chúng tôi sẽ nêu ra nếu
người dùng yêu cầu một chủ đề mà họ không nên xem.
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Sau khi nhận được yêu cầu chủ đề, chúng tôi đảm bảo người dùng của
chủ đề khớp với người dùng hiện đang đăng nhập trước khi hiển thị
trang. Nếu người dùng hiện tại không sở hữu chủ đề được yêu cầu,
chúng tôi sẽ đưa ra ngoại lệ Http404 (2) và Django trả về trang lỗi 404.
• Bây giờ nếu bạn cố gắng xem các mục chủ đề của người dùng khác, bạn
sẽ thấy thông báo Không tìm thấy trang từ Django.
• Bảo vệ trang edit_entry
• Các trang edit_entry có URL ở dạng
http://localhost:8000/edit_entry/entry_id/, khientry_id là một số.
• Hãy bảo vệ trang này để không ai có thể sử dụng URL để truy cập vào
các mục nhập của người khác:
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Bảo vệ trang edit_entry

views.py --snip-@login yêu cầu def


entry_id):

"Chỉnh sửa một mục hiện có.


entry = Entry. đối tượng.
mục chủ đề. chủ đề nếu chủ đề.
chủ sở hữu != yêu cầu. người
dùng: nâng cao Http404
nếu có yêu cầu. phương pháp 'POST':
--Snip--
2.3. Cho phép người dùng đến Sở hữu Của
họ Dữ liệu
• Liên kết các chủ đề mới với người dùng hiện tại
• Hiện tại, trang của chúng tôi để thêm chủ đề mới đã bị hỏng, vì nó
không liên kết các chủ đề mới với bất kỳngười dùng khớp p nào.
• Nếu bạn thử thêm một chủ đề mới, bạn sẽ thấy thông báo lỗi
IntegrityError cùng với ràng buộc NOT NULL không thành công:
learning_logs_topic.owner_id.
• Django nói rằng bạn không thể tạo một chủ đề mới mà không chỉ định
giá trị cho chủ sở hữu của chủ đề.
đến
2.3. Cho phép người dùng sở hữu dữ liệu của
họ
• Liên kết các chủ đề mới với người dùng hiện tại
• Có một cách khắc phục đơn giản cho vấn đề này, bởi vì chúng tôi có
quyền truy cập vào người dùng hiện tại thông qua đối tượng yêu cầu.
Thêm mã sau, liên kết chủ đề mới với người dùng hiện tại:
đến
2.3. Cho phép người dùng sở hữu dữ liệu của
họ
• Liên kết các chủ đề mới với người dùng hiện tại

wews.py --SNLP--
@login yêu cầu def chủ đề mới
(yêu cầu) : """Thêm chủ đề
mới. """ nếu yêu cầu. phương
pháp ' POST':
# Không có dữ liệu nào được gửi; Tạo một
biểu mẫu trống. hình thức TopicForm() khác:
# POST dữ liệu đã gửi; xử lý dữ liệu.
hình thức = nếu new_topic = hình
thức.
đến
new_topic.owner = yêu cầu.
new_topic người dùng. save() return
redirect( ' learning_logs : topics ')
# Hiển thị một biểu mẫu trống hoặc không hợp lệ. context =
{'form': form} return render(request, 'learning_logs/new
topic.html' , context)
--Snip--

2.3. Ngườidùng llowing sở hữu dữ liệu của


họ
• Liên kết các chủ đề mới với người dùng hiện tại
• Khi chúng ta lần đầu tiên gọi form.save(), chúng ta truyền đối số
commit-False vì chúng ta cần sửa đổi chủ đề mới trước khi lưu nó vào
cơ sở dữ liệu (1).
đến
• Sau đó, chúng tôi đặt chủ sở hữu của chủ đề mới attribute cho người
dùng hiện tại (2).
• Cuối cùng, chúng ta gọi save() trên đối tượng topic vừa định nghĩa w.
Bây giờ chủ đề có tất cả các dữ liệu cần thiết và sẽ lưu thành công.

You might also like