12

Django の URL パターンをいくつか定義しており、特定のパターンに関連付けられた正規表現を取得したい場合があります。これらの正規表現をクライアントに渡したいので、クライアントでもURLをチェックし(ブラウザ側の履歴操作について話している)、一致したときに適切なハンドラーを(JavaScriptで)起動できるようにしたいからです。

たとえば、私が持っている場合:

# 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 が翻訳します)。名前空間を使用していることに注意してください。何か案は?ジャンゴ1.5.

また、渡された名前に関連付けられた urlpattern オブジェクトを返す関数を作成することもできましたが、 return を実行しましurl.regex.pattern'^profile/(?P<slug>.*)$。ご覧のとおり、主要な はありません^user/

4

5 に答える 5

2

そこにはいくつかのJavaScriptreverse実装があります。

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

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

これは正規表現ではありませんが、サーバーで行うのと同じようにクライアント コードで URL をテストできるので、私の意見ではさらに優れています。

編集: URL 引数を無視する必要があるため、django-js hereのソースからアイデアを得ることができます。オプションの URL 引数はすでに削除されているため、おそらく説明したものと非常によく似ています。

コードは、各引数の部分正規表現から を削除するすべてのパターンを反復処理する?Pため、それらを に置き換えるだけ.*です。

ポイントは、実装を行うために必要になる可能性のあるすべての正規表現がそのソースにあるということです。24 ~ 29 行目のグローバル パターンを参照してください。

于 2013-09-06T08:37:23.090 に答える
2

So I've tried few things and finally I came up with my own solution. First I convert urlpatterns into a form which JavaScript understands:

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

Then I call generate_paths(urlpatterns), JSON-stringify the result and pass it to JavaScript (note that in JavaScript I have to convert regular expressions as strings to RegExp objects). In JavaScript I have

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...
};

Now in // do something... I can do something with names and args. For example I can keep a dictionary of named handlers, I can search for a handler (based on names) and call it with args.

That's the solution that works for me. Converting urlpatterns to JavaScript patterns might not be perfect (since converter seems to be a bit too simplified) but it works in most simple cases.

于 2013-09-13T10:05:41.133 に答える
1

答えではありませんが、これを見ている他の誰かに役立つかもしれません。

URLRegexResolvers以下は、 @Freakish のコードに基づいて、ネストされた を含む、Django プロジェクトのすべての完全な URL パターンのリストを生成します。

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))
于 2016-10-04T11:07:11.613 に答える
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]
于 2013-09-06T09:21:20.613 に答える