Django_路由详

动态路由和动态参数捕获

动态路由:url支持正则表达式, 访问的url能够匹配成功就去执行对应的视图函数

捕获参数:

# 捕获参数,位置传参
url(r'^data/([0-9]{4})/([0-2][0-9])/',function)
# 关键字传参
url(r'^data/(?P<year>[0-9]{4})/(?P<day>[0-2][0-9])/',function)

  视图函数中要给参数预留位置

路由分发

将不同功能的路由进行拆分, 将以某个匹配开头的路由分发到指定包去处理, 继续匹配后面内容

from django.conf.urls import include, url

urlpatterns=[
    url("^app01", include("app01.url")) # 这里写导入路径或者把url导入进来写在这里都可以   
]

app01.urls

from django.conf.urls import include, url

urlpatterns=[
    url("nihao", func)
]

include -  返回的是个元组

def include(arg, namespace=None, app_name=None):
    if app_name and not namespace:
        raise ValueError('Must specify a namespace if specifying app_name.')
    if app_name:
        warnings.warn(
            'The app_name argument to django.conf.urls.include() is deprecated. '
            'Set the app_name in the included URLconf instead.',
            RemovedInDjango20Warning, stacklevel=2
        )

    if isinstance(arg, tuple):
        # callable returning a namespace hint
        try:
            urlconf_module, app_name = arg
        except ValueError:
            if namespace:
                raise ImproperlyConfigured(
                    'Cannot override the namespace for a dynamic module that provides a namespace'
                )
            warnings.warn(
                'Passing a 3-tuple to django.conf.urls.include() is deprecated. '
                'Pass a 2-tuple containing the list of patterns and app_name, '
                'and provide the namespace argument to include() instead.',
                RemovedInDjango20Warning, stacklevel=2
            )
            urlconf_module, app_name, namespace = arg
    else:
        # No namespace hint - use manually provided namespace
        urlconf_module = arg

    if isinstance(urlconf_module, six.string_types): # 字符串类型的就导入进来
        urlconf_module = import_module(urlconf_module)
    patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
    app_name = getattr(urlconf_module, 'app_name', app_name)
    if namespace and not app_name:
        warnings.warn(
            'Specifying a namespace in django.conf.urls.include() without '
            'providing an app_name is deprecated. Set the app_name attribute '
            'in the included module, or pass a 2-tuple containing the list of '
            'patterns and app_name instead.',
            RemovedInDjango20Warning, stacklevel=2
        )

    namespace = namespace or app_name

    # Make sure we can iterate through the patterns (without this, some
    # testcases will break).
    if isinstance(patterns, (list, tuple)):
        for url_pattern in patterns:
            # Test if the LocaleRegexURLResolver is used within the include;
            # this should throw an error since this is not allowed!
            if isinstance(url_pattern, LocaleRegexURLResolver):
                raise ImproperlyConfigured(
                    'Using i18n_patterns in an included URLconf is not allowed.')

    return (urlconf_module, app_name, namespace)


def url(regex, view, kwargs=None, name=None):
    if isinstance(view, (list, tuple)):
        # For include(...) processing.
        urlconf_module, app_name, namespace = view
        return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
    elif callable(view):
        return RegexURLPattern(regex, view, kwargs, name)
    else:
        raise TypeError('view must be a callable or a list/tuple in the case of include().')

反向解析和名称空间

反向解析的应用场景 :  在试图函数和模板中写了很多跳转的路由, 然后领导要求把urlpatterns里面改了,,, 改了这里相关的试图和html中的也要改,,,很容易漏掉

反向解析就为此而生

无参路由

首先要为路由设置一个名字

urlpatterns = [
      url("aaaa", func, name="name")
]

在视图中使用

from django.urls import reverse

reverse('name')

模板中使用

{% url "name" %}

有参路由

同上

urlpatterns = [
      url("aaaa/(/d+)", func, name="name")
]

在视图中使用

from django.urls import reverse

reverse('name', args=(1,)) # 无名参数, 按位置传
reverse('name', kwargs={"1":1}) # 命名参数, 按关键字传

在路由中使用

{% url "name"  1 %} # 按位置传
{% url "name" q1="1" %} # 按关键字传

名称空间

对于include其中的路由出现的同名现象, 不同功能中的路由可能是不同的人写的, 对于出现的同名的路由, 前面的那个会被替换.

urlpatterns=[
    url("^app01", include("app01.url", namespace="app01"))
    url("^app02", include("app02.url", namespace="app02"))
]

当设置了namespace时, 反向解析时必须用到

from django.urls import reverse
reverse('app01:name')
# 带参数的同上

路由中使用

{% url "app01:name" %}

  

posted @ 2018-10-12 09:27  瓜田月夜  阅读(142)  评论(0编辑  收藏  举报