Tôi cần sử dụng chế độ xem dựa trên lớp học, nhưng tôi muốn có thể sử dụng tên đầy đủ của lớp trong URLconf mà không phải khởi tạo lớp xem trước khi sử dụng. Có gì giúp tôi là một metaclass đáng ngạc nhiên đơn giản:
class CallableViewClass(type):
def __call__(cls, *args, **kwargs):
if args and isinstance(args[0], HttpRequest):
instance = super(CallableViewClass, cls).__call__()
return instance.__call__(*args, **kwargs)
else:
instance = super(CallableViewClass, cls).__call__(*args, **kwargs)
return instance
class View(object):
__metaclass__ = CallableViewClass
def __call__(self, request, *args, **kwargs):
if hasattr(self, request.method):
handler = getattr(self, request.method)
if hasattr(handler, '__call__'):
return handler(request, *args, **kwargs)
return HttpResponseBadRequest('Method Not Allowed', status=405)
tôi bây giờ có thể cả hai nhanh chóng lớp xem và sử dụng các trường hợp như xem chức năng, HOẶC tôi chỉ đơn giản có thể chỉ URLconf tôi đến lớp của tôi và có thuyết minh metaclass (và cuộc gọi) lớp xem cho tôi. Điều này hoạt động bằng cách kiểm tra đối số đầu tiên là __call__
- nếu đó là một HttpRequest
, nó phải là một yêu cầu HTTP thực tế bởi vì sẽ vô nghĩa khi thực hiện khởi tạo lớp xem với một phiên bản HttpRequest
.
class MyView(View):
def __init__(self, arg=None):
self.arg = arg
def GET(request):
return HttpResponse(self.arg or 'no args provided')
@login_required
class MyOtherView(View):
def POST(request):
pass
# And all the following work as expected.
urlpatterns = patterns(''
url(r'^myview1$', 'myapp.views.MyView', name='myview1'),
url(r'^myview2$', myapp.views.MyView, name='myview2'),
url(r'^myview3$', myapp.views.MyView('foobar'), name='myview3'),
url(r'^myotherview$', 'myapp.views.MyOtherView', name='otherview'),
)
(tôi đã đăng một đoạn mã cho điều này tại http://djangosnippets.org/snippets/2041/)
Thực thi Python không phải là nút cổ chai, nhưng có thể ảnh hưởng đến khả năng mở rộng trang web và hiệu suất tổng thể. Tôi rất vui vì memcache tồn tại! – StefanNch