2013-09-06 6 views
10

मेरे पास ऐसा कोई मामला है जहां मैंने कुछ Django url पैटर्न परिभाषित किए हैं और अब मैं किसी दिए गए पैटर्न से जुड़े नियमित अभिव्यक्ति को पुनर्प्राप्त करना चाहता हूं। मैं चाहता हूं क्योंकि मैं क्लाइंट को इन नियमित अभिव्यक्तियों को पास करना चाहता हूं, इसलिए मैं क्लाइंट में यूआरएल भी देख सकता हूं (मैं ब्राउजर साइड हिस्ट्री मैनिपुलेशन के बारे में बात कर रहा हूं) और एक मैच होने पर उपयुक्त हैंडलर (जावास्क्रिप्ट में) आग लगाना।Django नाम से यूआरएल रेगेक्स प्राप्त करें

उदाहरण के लिए अगर मेरे पास है:

# urls.py 
urlpatterns = patterns("", 
    url(r"^$", Index.as_view(), name="index"), 
    url(r"^user/", include("User.urls", namespace="User")), 
) 

# User/urls.py 
urlpatterns = patterns("", 
    url(r"^profile/(?P<slug>.*)$", GetProfile.as_view(), name="get_profile") 
) 

तो मैं निम्नलिखित समारोह की जरूरत है:

>>> get_regex("User:get_profile") 
'^user/profile/(?P<slug>.*)$' 

(या Django इसकी अनुवाद हालांकि)। ध्यान दें कि मैं नामस्थान का उपयोग कर रहा हूं। कोई विचार? Django1.5।

इसके अलावा मैंने एक ऐसा फ़ंक्शन लिखने में कामयाब रहा है जो उत्तीर्ण नाम से जुड़े urlpattern ऑब्जेक्ट को लौटाता है, हालांकि url.regex.pattern'^profile/(?P<slug>.*)$ देता है। तो जैसा कि आप देख सकते हैं कि कोई अग्रणी नहीं है।

+0

आप views.py का एक टुकड़ा यह उपयोगी हो सकता है – drabo2005

+0

@ drabo2005 कैसे मददगार होगा दिखा सकते हैं? सामग्री अप्रासंगिक है। – freakish

+0

@freakish बस एक सूचक: यदि आप 'dgeango.core.urlresolvers.py' में' RegexURLResolver' कक्षा को देखते हैं, तो इसकी एक 'reversed_dict' संपत्ति है। इसमें वह पैटर्न होना चाहिए जिसे आप ढूंढ रहे हैं। लाइन 385, एक ही फाइल पर एक नज़र डालें। – Germano

उत्तर

2

इसलिए मैंने कुछ चीजों की कोशिश की है और अंत में मैं अपने स्वयं के समाधान के साथ आया हूं।

import re 
converter = re.compile(r"\?P<.*?>") 

def recursive_parse(urlpatterns, lst): 
    for pattern in urlpatterns: 
     obj = { 
      "pattern": converter.sub("", pattern.regex.pattern) 
     } 
     if hasattr(pattern, "name") and pattern.name is not None: 
      obj["name"] = pattern.name 
     if hasattr(pattern, "namespace"): 
      obj["namespace"] = pattern.namespace 

     if hasattr(pattern, "url_patterns"): 
      if "urls" not in obj: 
       obj["urls"] = [] 
      recursive_parse(pattern.url_patterns, obj["urls"]) 

     lst.append(obj) 


def generate_paths(urlpatterns): 
    paths = [] 
    recursive_parse(urlpatterns, paths) 
    return paths 

तब मैं generate_paths(urlpatterns), परिणाम JSON-stringify और यह जावास्क्रिप्ट को पारित फोन (ध्यान दें कि जावास्क्रिप्ट में मैं RegExp वस्तुओं के लिए तारों के रूप में नियमित अभिव्यक्ति कन्वर्ट करने के लिए है): सबसे पहले मैं एक रूप है जो जावास्क्रिप्ट को समझता में urlpatterns कन्वर्ट । जावास्क्रिप्ट में मैं

var recursive_check = function(url, patterns, names, args) { 
    var l = patterns.length; 
    for (var i = 0; i < l; i++) { 
     var pat = patterns[i], 
      match = pat.pattern.exec(url); 
     pat.lastIndex = 0; 
     if (match) { 
      names.push(pat.namespace || pat.name); 
      var f = match.shift(), 
       url = url.replace(f, ""), 
       ml = match.length; 
      for (var j = 0; j < ml; j++) { 
       args.push(match[j]); 
      } 
      if (pat.urls) { 
       recursive_check(url, pat.urls, names, args); 
      } 
      break; 
     } 
    } 
}; 

var fire_handler = function(url) { 
    var names = [], args = []; 
    recursive_check(url, patterns, names, args); 
    // do something... 
}; 

अब // do something... में मैं names और args साथ कुछ कर सकते हैं की है। उदाहरण के लिए, मैं नामित हैंडलर का शब्दकोश रख सकता हूं, मैं एक हैंडलर (names पर आधारित) की खोज कर सकता हूं और इसे args पर कॉल कर सकता हूं।

यह समाधान है जो मेरे लिए काम करता है। urlpatterns को जावास्क्रिप्ट पैटर्न में कनवर्ट करना सही नहीं हो सकता है (क्योंकि converter थोड़ा सा सरलीकृत लगता है) लेकिन यह सबसे साधारण मामलों में काम करता है।

2

वहाँ कई जावास्क्रिप्ट reverse कार्यान्वयन हैं।

http://djangojs.readthedocs.org/en/latest/djangojs.html#reverse-urls

https://github.com/version2/django-js-reverse

यह regex नहीं है, लेकिन आप अपने ग्राहक कोड में यूआरएल का परीक्षण कर सकते हैं जैसे आप सर्वर में करते हैं, तो यह भी मेरी राय में बेहतर है।

संपादित: चूंकि आप यूआरएल तर्कों की अनदेखी करने की जरूरत है, तो आप Django-js here के स्रोत से एक विचार प्राप्त कर सकते हैं। यह पहले से ही वैकल्पिक यूआरएल तर्क हटा देता है, इसलिए यह संभवत: आपके वर्णन के समान ही है।

कोड प्रत्येक तर्क subregex से ?P को हटाने के हर पैटर्न पर पुनरावृत्त करता है ताकि आप उन्हें .* से प्रतिस्थापित कर सकें।

बिंदु यह है कि आपके पास उस स्रोत में प्रत्येक रेगेक्स है जिसे आपको संभवतः अपना कार्यान्वयन करने की आवश्यकता हो सकती है। 24-29 लाइनों में वैश्विक पैटर्न देखें।

+0

यह मेरा मामला नहीं है। मैं यूआरएल को रिवर्स करने की कोशिश नहीं कर रहा हूं। मैं regex प्राप्त करने की कोशिश कर रहा हूं ताकि अगर कोई यूआरएल जावास्क्रिप्ट में रेगेक्स से मेल खाता है तो मैं एक हैंडलर को आग लगा सकता हूं। – freakish

+0

लेकिन क्या अंतर है? क्या आप अभी नहीं कर सकते हैं अगर (url === रिवर्स ('नाम')) ' –

+0

अंतर यह है कि यूआरएल में ऊपर दिखाए गए उदाहरण में' स्लग 'जैसे अतिरिक्त तर्क हो सकते हैं। तो यूआरएल दिया गया है (उदाहरण के लिए) '/ user/profile/root' और आप 'रिवर्स' के साथ क्या कहेंगे? मुझे इसे रेगेक्स से मिलान करने की ज़रूरत है। – freakish

1

इस प्रयास करें:

from django.core.urlresolvers import get_resolver 

resolver = get_resolver(None) 
url = resolver.reversed_dict.getlist('get_profile') 
if url: 
    pattern = url[0][1] 
+0

सबसे पहले: 'resolver.reverse_dict' पॉप्युलेट हो जाता है जब 'रिवर्स' कहा जाता है (जो मेरे मामले में बिल्कुल नहीं हो सकता है)। दूसरा: एक ही मुद्दा: इसमें यूआरएल (..., शामिल (...)) के कारण पूरे यूआरएल पैटर्न (उपसर्ग '^ उपयोगकर्ता/'गायब नहीं होगा)। – freakish

+0

@freakish मैंने अपने खोल में कोड चलाने की कोशिश की और मुझे उपसर्ग के साथ, संपूर्ण पैटर्न मिला। मुझे '^' हालांकि नहीं मिलता है। क्या आप वाकई 'reverse_dict' को आलसी नहीं आते हैं जब भी इसे बुलाया जाता है? – Germano

+0

वास्तव में मैं इसे 'get_profile' मार्ग के साथ बिल्कुल पॉप्युलेट नहीं कर सका। क्या आप वाकई 'शामिल' के साथ 'urlpatterns' का उपयोग कर रहे हैं? यह 'रिज़ॉल्वर' ऑब्जेक्ट केवल शीर्ष स्तर के यूआरएल पैटर्न रखने के लिए प्रतीत होता है। समस्या पैटर्न के साथ है जो अन्य पैटर्न में शामिल हैं। – freakish

0

जहां तक ​​मैं समझ गया, किसी विशेष दृश्य के regex अभिव्यक्ति (और नहीं यूआरएल) लौटने में सक्षम होना चाहता हूँ।

समारोह urlRegexURLResolver का एक उदाहरण प्रस्तुत करती है:

यह समाधान के अपने संक्षिप्त वर्णन है। यह वर्ग रेगेक्स स्टोर करता है, क्योंकि यह LocaleRegexProvider पर __init__ (in this line और this line) पर कॉल करता है।

तो, मुझे लगता है कि आप

  1. रिवर्स देखने के साथ साथ नाम स्थान
  2. पहला तर्क की tuples urlpatterns
  3. वापसी _regex, LocaleRegexProvider._regex (के टपल से उस दृश्य की टपल मिल खोज कर सकते हैं या regex()), दृश्य के संबंध में tuple के।

मुझे यकीन नहीं है कि यह काम करता है (परीक्षण नहीं किया गया), न तो यह सबसे अच्छा समाधान है, लेकिन कम से कम आपके पास कुछ लिंक हैं जहां Django रेगेक्स स्टोर करता है।

+0

हां, यह बहुत अधिक है जिसका अर्थ है "मैंने एक फ़ंक्शन लिखने में कामयाब" भाग लिया है। दुर्भाग्यवश '_regex' (जो' .regex.pattern' जैसा ही प्रतीत होता है) केवल अपनी नियमित अभिव्यक्ति ('url (...) में परिभाषित) के बारे में जानकारी रखता है, न कि संपूर्ण पथ (इसमें ' यूआरएल (..., शामिल (...)) ')। – freakish

0

कोई जवाब नहीं है लेकिन यह किसी और के लिए उपयोगी हो सकता है।

निम्नलिखित @ फ्रैंकिश कोड के आधार पर, नेस्टेड URLRegexResolvers के लिए Django प्रोजेक्ट में यूआरएल पैटर्न को पूरा करने, सभी यूआरएल पैटर्न की एक सूची उत्पन्न करता है।

import re 
from django.core.urlresolvers import get_resolver 

converter = re.compile(r"\?P<.*?>") 

def trim_leading_caret(s): 
    return s[1:] if s.startswith('^') else s 

def recursive_parse(urlpatterns, lst, prefix=None): 
    for pattern in urlpatterns: 
     path = (prefix or '') + trim_leading_caret(converter.sub("", pattern.regex.pattern)) 
     if hasattr(pattern, "url_patterns"): 
      recursive_parse(pattern.url_patterns, lst, path) 
     else: 
      lst.append('^' + path) 

def generate_paths(urlpatterns): 
    paths = [] 
    recursive_parse(urlpatterns, paths) 
    return paths 

generate_paths(get_resolver(None)) 
संबंधित मुद्दे