Получение списка имен slug по имени пути к url

Я занимаюсь реверс-инжинирингом urlpatterns в django. Для моей цели мне нужно динамически узнать список имен slug, которые разработчики решили использовать в url.

Пример:

path("<slug:membership_slug>/<slug:parent_slug>/data/", rzd.ReportingUnitDataView.as_view(), name="hierarchy.item.data"),

Итак, в мире, где все пишут идеальный код, моя функция принимает "hierarcy.item.data" и выплевывает ["membership_slug", "parent_slug"]

Я посмотрел на обратную функцию, надеясь, что она вернет что-то полезное без kwargs, но это не так. Гуглил как Neo, но безрезультатно. Но надежда не покидает мое сердце... где-то в django должен храниться весь этот urlpatterns материал! Я все еще верю.

Возможно, вы можете подсказать, как получить список урлов, пусть даже в сыром формате, это уже будет помощью. Спасибо.

Найдите книгу под названием Django 2x scopes в этой книге собрано все, что связано с лучшими практиками django и, конечно же, часть про урлы.

Эта книга поможет вам лучше понять, как думают разработчики django.

Счастливого взлома 🙃

Думаю, лучше всего написать Regex.

Из того, что я нашел в исходном коде, они используют _lazy_re_compile(r'<(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)>'), который можно найти urls\resolvers.py в _route_to_regex

вот что у меня получилось после того, как я перелопатил исходный код

def geturlnamedarguments(route):
    from django.utils.regex_helper import _lazy_re_compile
    named_arguments = []
    while True:
        match = _lazy_re_compile(r'<(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)>').search(route)
        if not match:
            break
        route = route[match.end():]
        parameter = match['parameter']
        named_arguments.append(parameter)
    return named_arguments

Вы также можете получить необработанный URL-маршрут в виде строки, выполнив

urlpatterns[index].pattern._route

Вы можете найти объект URLPattern также в urls\resolvers.py, если хотите поиграть с ним... Я так и не нашел места, где есть имена в необработанном формате

Решено, Мне пришло в голову, что я могу просто включить urls.py и разобрать его самостоятельно :)

from myapp import urls


class UrlPatterns:

    @staticmethod
    def _get_params(s):
        items = []
        is_exp = False
        is_prefix = False
        type = ''
        name = ''
        for n in range(len(s)):
            if not is_exp:
                if s[n] == '<':
                    is_exp = True
                    is_prefix = True
                    type = ''
            elif is_prefix:
                if s[n] == ':':
                    is_prefix = False
                else:
                    type += s[n]
            else:
                if s[n] == '>':
                    is_exp = False
                    items.append({
                        'type': type,
                        'name': name
                    })
                    name = ''
                else:
                    name += s[n]

        return items

    @staticmethod
    def _find_pattern(url_name):
        for url in urls.urlpatterns:
            if url.name == url_name:
                return str(url.pattern)
        return None

    @staticmethod
    def get_required_params(url_name):
        url_pattern = UrlPatterns._find_pattern(url_name)
        if url_pattern:
            return UrlPatterns._get_params(url_pattern)
        return None
Вернуться на верх