मुझे कक्षा आधारित विचारों का उपयोग करने की आवश्यकता थी, लेकिन मैं इसे अपने URLconf में कक्षा के पूर्ण नाम का उपयोग करने में सक्षम होना चाहता था, इसे हमेशा उपयोग करने से पहले दृश्य वर्ग को तुरंत चालू करने के बिना। मुझे आश्चर्य की बात है कि एक आश्चर्यजनक सरल मेटाक्लास था:
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)
अब मैं दोनों दृश्य कक्षाओं को तत्काल कर सकता हूं और उदाहरणों का उपयोग कार्यों के रूप में देख सकता हूं, या मैं बस अपने यूआरएल कॉन्फ़िगर को मेरी कक्षा में इंगित कर सकता हूं और मेटाक्लास तुरंत मेरे लिए व्यू क्लास (और कॉल) कर सकता हूं। यह __ कॉल __
पर पहला तर्क जांचकर काम करता है? यदि यह एक HttpRequest
है, तो यह एक वास्तविक HTTP अनुरोध होना चाहिए क्योंकि दृश्य कोड को 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'),
)
(मैंने इसके लिए http://djangosnippets.org/snippets/2041/ पर एक स्निपेट पोस्ट किया है)