Có, có thể, nhưng không quá đơn giản. Yếu tố phức tạp là thiết kế trang trí login_required
của Django thực sự đi qua 2 cấp độ không xác định (một hàm động và một trang trí khác), để kết thúc tại django.contrib.auth.decorators._CheckLogin, là một lớp với phương thức __call__
.
Hãy nói rằng bạn có một tổ chức phi django, vườn nhiều chức năng trang trí trông như thế này:
def my_decorator(func):
def inner():
return func()
return inner
@my_decorator
def foo():
print foo.func_name
# results in: inner
Kiểm tra để xem nếu chức năng foo
đã được bọc có thể đơn giản như kiểm tra tên đối tượng chức năng của . Bạn có thể làm điều này bên trong hàm. Tên sẽ thực sự là tên của hàm wrapper cuối cùng. Đối với các trường hợp phức tạp hơn, bạn có thể sử dụng mô-đun inspect
để đi bộ lên các khung bên ngoài từ khung hiện tại nếu bạn đang tìm kiếm một thứ gì đó cụ thể.
Trong trường hợp của Django, tuy nhiên, thực tế là trang trí thực sự là một thể hiện của lớp _CheckLogin
có nghĩa là chức năng không phải là thực sự là một chức năng, và do đó không có func_name
tài sản: cố gắng đoạn mã trên sẽ nâng cao một ngoại lệ .
Nhìn vào mã nguồn cho django.contrib.auth.decorators._CheckLogin
, tuy nhiên, cho thấy trường hợp _CheckLogin
sẽ có thuộc tính login_url
.Đây là một điều khá đơn giản để kiểm tra:
@login_required
def my_view(request):
is_private = hasattr(my_view, 'login_url')
Vì _CheckLogin
cũng được sử dụng để thực hiện trang trí auth khác, phương pháp này cũng sẽ làm việc cho permission_required
, vv Tôi đã không bao giờ thực sự có nhu cầu sử dụng này Tuy nhiên, tôi thực sự không thể bình luận về những gì bạn nên tìm kiếm nếu bạn có nhiều trang trí xung quanh một cái nhìn duy nhất ... một bài tập còn lại cho người đọc, tôi đoán (kiểm tra ngăn xếp khung?).
Như lời khuyên biên tập không được kiểm tra, tuy nhiên, tôi sẽ nói kiểm tra chức năng để xem liệu nó có được bọc như thế này đánh tôi một chút không. Bạn có thể tưởng tượng tất cả các loại hành vi không thể đoán trước đang chờ xảy ra khi một nhà phát triển mới đến dự án như tát trên một số trang trí khác. Trong thực tế, bạn cũng tiếp xúc với những thay đổi trong khuôn khổ django chính nó ... một nguy cơ bảo mật chờ đợi để xảy ra.
Tôi muốn giới thiệu phương pháp tiếp cận của Van Gale vì lý do đó là điều gì đó rõ ràng và do đó triển khai mạnh mẽ hơn nhiều.
Khối mã đầu tiên của bạn sẽ không hoạt động như văn bản. my_decorator hủy bỏ chức năng được truyền cho nó, vì vậy việc đặt một lệnh in trong foo là vô ích. –
Cảm ơn David, bạn nói đúng ... Tôi đã lướt qua khối đầu tiên để đến điểm chính mà không cần đọc kỹ những gì tôi đã gõ. Đánh giá cao bản chỉnh sửa. –
Cảm ơn bạn đã trả lời sâu. Kết luận của bạn là những gì tôi đã làm, mặc dù tôi nghĩ rằng có thể có thêm một số "pythonic;" Tôi nghĩ rằng trong trường hợp của tôi làm điều này "đúng" cách là quá phức tạp và không phải là rất mạnh mẽ. –