<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          獲取 Django 項目下全部 URL,一個函數(shù)輕松搞定

          共 5855字,需瀏覽 12分鐘

           ·

          2021-07-07 09:27

          廢話不多說,直接上代碼。

          from django.urls import get_resolver, URLPattern, URLResolver


          def get_all_url(resolver=None, pre='/'):
              if resolver is None:
                  resolver = get_resolver()
              for r in resolver.url_patterns:
                  if isinstance(r, URLPattern):
                      if '<pk>' in str(r.pattern):
                          continue
                      yield pre + str(r.pattern).replace('^''').replace('$'''), r.name
                  if isinstance(r, URLResolver):
                      yield from get_all_url(r, pre + str(r.pattern))


          if __name__ == '__main__':
              # 獲取項目全部 url
              for url, name in get_all_url():
                  print("url='{}'  name='{}'".format(url, name))

              # 獲取某個 app 下的全部 url
              # 假設有一個 app 叫 dashboard
              # 通過 pre 參數(shù)傳入相應前綴
              for url, name in get_all_url(get_resolver('dashboard.urls')):
                  print("url='{}'  name='{}'".format(url, name))

          其中用到的函數(shù)就是 get_resolver,讓我們看看源碼,這個函數(shù)應該怎么用。

          # django/urls/resolvers.py

          def get_resolver(urlconf=None):
              if urlconf is None:
                  urlconf = settings.ROOT_URLCONF
              return _get_cached_resolver(urlconf)


          @functools.lru_cache(maxsize=None)
          def _get_cached_resolver(urlconf=None):
              return URLResolver(RegexPattern(r'^/'), urlconf)

          傳入?yún)?shù) urlconf,參數(shù)有個默認值 settings.ROOT_URLCONF,打印出來是 myproject.urls,其實就是項目全局下的路由文件。

          返回值是 URLResolver 類,這個類就比較復雜了,看了源碼也不是很明白應該怎么處理這個類。

          # django/urls/resolvers.py

          class URLResolver:
              # 省略了一堆代碼

              @cached_property
              def urlconf_module(self):
                  if isinstance(self.urlconf_name, str):
                      return import_module(self.urlconf_name)
                  else:
                      return self.urlconf_name

              @cached_property
              def url_patterns(self):
                  # urlconf_module might be a valid set of patterns, so we default to it
                  patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                  try:
                      iter(patterns)
                  except TypeError as e:
                      msg = (
                          "The included URLconf '{name}' does not appear to have any "
                          "patterns in it. If you see valid patterns in the file then "
                          "the issue is probably caused by a circular import."
                      )
                      raise ImproperlyConfigured(msg.format(name=self.urlconf_name)) from e
                  return patterns

          不過還是有一個方法引起了我的注意,畢竟我們要取 url,那跟 url 相關的函數(shù)還是要特殊關照一下。

          打印一下這個結(jié)果,看看有沒有發(fā)現(xiàn)。

          print(get_resolver('myproject.urls').url_patterns)

          # 輸出
          # [
          # ...
          # <URLPattern 'api/v1/api-doc' [name='api-doc']>, 
          # <URLResolver <URLPattern list> (api-docs:api-docs) # 'api/v1/drf-api-doc'>]

          結(jié)果是一個列表,元素有兩種,分別是 URLPattern 類和 URLResolver 類。

          # django/urls/resolvers.py

          class URLPattern:
              def __init__(self, pattern, callback, default_args=None, name=None):
                  self.pattern = pattern
                  self.callback = callback  # the view
                  self.default_args = default_args or {}
                  self.name = name

          前者可以直接就拿 self.pattern 就是對應 url,而后者再遞歸調(diào)用也同樣可以拿到結(jié)果。

          到這里就可以宣布大功告成了。


          關注公眾號 AlwaysBeta,各種后端開發(fā)技術(shù)干貨。

          題圖: Image by Rickson Bejar from Pixabay

          參考文章:

          • https://www.ikaze.cn/article/60

          大家都在看:

          瀏覽 55
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色高潮喷水网站 | 免费观看色情 | 久久电影伊人 | 午夜神马福利片 | 午夜黄网|