साइट लोड होने के लिए हाइब्रिड दृष्टिकोण का उपयोग करना आपके लिए उपयोगी हो सकता है।
def groupfinder(userid, request):
user = request.db.query(User).filter_by(id=userid).first()
if user is not None:
# somehow get the list of sites they are members
sites = user.allowed_sites
return ['site:%d' % s.id for s in sites]
class SiteFactory(object):
def __init__(self, request):
self.request = request
def __getitem__(self, key):
site = self.request.db.query(Site).filter_by(id=key).first()
if site is None:
raise KeyError
site.__parent__ = self
site.__name__ = key
site.__acl__ = [
(Allow, 'site:%d' % site.id, 'view'),
]
return site
हम प्रिंसिपलों के लिए उपयोगकर्ताओं को मैप करने के लिए groupfinder का उपयोग करेंगे। हमने यहां उन्हें केवल उन साइटों पर मैप करने के लिए चुना है जिनके पास उनकी सदस्यता है। हमारे सरल ट्रैवर्सल को केवल रूट ऑब्जेक्ट की आवश्यकता होती है। यह को __acl__
के साथ लोड किया गया है जो groupfinder
बनाने के लिए एक ही प्रिंसिपल का उपयोग करता है।
आपको पिरामिड कुकबुक में request.db
दिए गए पैटर्न सेट अप करने की आवश्यकता होगी।
def site_pregenerator(request, elements, kw):
# request.route_url(route_name, *elements, **kw)
from pyramid.traversal import find_interface
# we use find_interface in case we improve our hybrid traversal process
# to take us deeper into the hierarchy, where Site might be context.__parent__
site = find_interface(request.context, Site)
if site is not None:
kw['site_id'] = site.id
return elements, kw
Pregenerator site_id
खोजने के लिए और अपने आप आपके लिए यूआरएल में जोड़ सकते हैं।
def add_site_route(config, name, pattern, **kw):
kw['traverse'] = '/{site_id}'
kw['factory'] = SiteFactory
kw['pregenerator'] = site_pregenerator
if pattern.startswith('/'):
pattern = pattern[1:]
config.add_route(name, '/site/{site_id}/' + pattern, **kw)
def main(global_conf, **settings):
config = Configurator(settings=settings)
authn_policy = AuthTktAuthenticationPolicy('seekrit', callback=groupfinder)
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(ACLAuthorizationPolicy())
config.add_directive(add_site_route, 'add_site_route')
config.include(site_routes)
config.scan()
return config.make_wsgi_app()
def site_routes(config):
config.add_site_route('site_users', '/user')
config.add_site_route('site_items', '/items')
हम यहां अपना आवेदन सेट अप करते हैं। हमने मार्गों को एक समावेशी समारोह में भी स्थानांतरित किया जो हमें मार्गों का अधिक आसानी से परीक्षण करने की अनुमति दे सकता है।
@view_config(route_name='site_users', permission='view')
def users_view(request):
site = request.context
हमारे विचार तब सरलीकृत किए जाते हैं। उन्हें केवल तभी बुलाया जाता है जब उपयोगकर्ता को साइट तक पहुंचने की अनुमति हो, और साइट ऑब्जेक्ट पहले से ही हमारे लिए लोड हो चुका है।
हाइब्रिड Traversal
एक कस्टम निर्देश add_site_route
जो स्वत: मार्ग के लिए ट्रेवर्सल समर्थन जोड़ देगा add_route
के चारों ओर एक आवरण के साथ अपने config
वस्तु को बढ़ाने के लिए जोड़ा गया है। जब उस मार्ग का मिलान किया जाता है, तो यह मार्ग पैटर्न से {site_id}
प्लेसहोल्डर ले जाएगा और इसका उपयोग करेगा क्योंकि आपके ट्रैवर्सल पथ (/{site_id}
पथ है जिसे हम परिभाषित करते हैं कि हमारे ट्रैवर्सल पेड़ को कैसे संरचित किया जाता है)।
ट्रैवर्सल पथ /{site_id}
पर होता है जहां पहला चरण पेड़ की जड़ (/
) ढूंढ रहा है। मार्ग SiteFactory
का उपयोग ट्रैवर्सल पथ की जड़ के रूप में ट्रैवर्सल करने के लिए किया गया है।इस वर्ग को रूट के रूप में तुरंत चालू किया गया है, और __getitem__
को उस कुंजी के साथ बुलाया जाता है जो पथ में अगला खंड है ({site_id}
)। फिर हमें उस साइट से मिलान करने वाली साइट ऑब्जेक्ट मिलती है और यदि संभव हो तो इसे लोड करें। find_interface
को काम करने की अनुमति देने के लिए साइट ऑब्जेक्ट को __parent__
और __name__
के साथ अपडेट किया गया है। इसे __acl__
के साथ बाद में वर्णित अनुमतियां प्रदान करने के साथ भी बढ़ाया गया है।
Pregenerator
प्रत्येक मार्ग एक pregenerator है कि एक अनुरोध के लिए ट्रेवर्सल पदानुक्रम में Site
का उदाहरण खोजने के लिए प्रयास करता है के साथ अद्यतन किया जाता है। यदि वर्तमान अनुरोध साइट-आधारित यूआरएल को हल नहीं करता है तो यह असफल हो सकता है। प्रीजेनरेटर साइट आईडी के साथ route_url
पर भेजे गए कीवर्ड अपडेट करता है।
प्रमाणीकरण
उदाहरण दिखाता है कि आप एक प्रमाणीकरण नीति है जो यह दर्शाता है कि इस प्रयोक्ता "साइट:" में है प्रधानाचार्यों, जो उपयोगकर्ता को नक्शे हो सकता है समूह। साइट (request.context
) को तब एसीएल कहने के लिए अपडेट किया गया है कि अगर site.id == 1
"साइट: 1" समूह में से किसी को "दृश्य" अनुमति होनी चाहिए। users_view
को तब "दृश्य" अनुमति की आवश्यकता के लिए अद्यतन किया जाता है। यदि उपयोगकर्ता को दृश्य तक पहुंच से वंचित कर दिया गया है तो यह HTTPForbidden
अपवाद उठाएगा। यदि आप चाहें तो 404 में सशर्त रूप से इसका अनुवाद करने के लिए आप एक अपवाद दृश्य लिख सकते हैं।
मेरे उत्तर का उद्देश्य यह दिखाने के लिए है कि कैसे एक हाइब्रिड दृष्टिकोण पृष्ठभूमि में एक यूआरएल के सामान्य भागों को संभालने से आपके विचारों को थोड़ा अच्छा बना सकता है। HTH।
पिरामिड के ट्रैवर्सल ज्ञान के मेरे रिसाव के कारण, मैं आपका उदाहरण पूरी तरह से समझ नहीं पा रहा हूं लेकिन मैं दस्तावेज़ों को पढ़ूंगा और इसे समझने की कोशिश करूंगा ... :-) बीटीडब्ल्यू: जब मैं अनुरोध करता हूं तो आपका समाधान 'site_id' पैरामीटर को खत्म कर सकता है .route_path? –
जब आप मार्ग उत्पन्न होते हैं तो साइट_आईडी में स्वचालित रूप से भरने वाले मार्गों पर प्रीजेनरेटर जोड़कर आप 'site_id' को समाप्त कर सकते हैं। यह स्पष्ट नहीं है, यही कारण है कि मैंने इसे अपनी भूख लगी है। लेकिन आपके विचार कुछ घोषणात्मक कॉन्फ़िगरेशन के साथ बहुत सरल हो सकते हैं। –
मैं अभी भी एक गड़बड़ में हूं ..... क्या आप इस उदाहरण के साथ अपना उदाहरण अपडेट करते हैं? धन्यवाद! वैसे, अगर मैं विभिन्न साइट के लिए अलग-अलग मार्ग जोड़ना चाहता हूं। टाइप, मैं क्या करूँ? उदाहरण के लिए, यदि site1.type 'पासपोर्ट' है और site1.id 1 है, site2.type 'www' है और site2.id 2 है/साइट/1/उपयोगकर्ता को देखने के लिए मैप किया जाना चाहिए, लेकिन/साइट/2/उपयोगकर्ता को 404 त्रुटि उठानी चाहिए। –