>>> from django.utils.regex_helper import normalize
>>> bits=normalize(r'^static/(?P<path>.*)$')
>>> bits
[(u'static/%(path)s', [u'path'])]
>>> bits=normalize(r'^static/(?P<path>.*)/(?P<order>.*)$')
>>> bits
[(u'static/%(path)s/%(order)s', [u'path', u'order'])]
normalize函数返回列表,列表的元素是元组,元组的第一项是字符串,第二项是组名字。

django.conf.url可以导入include,patterns,url等函数
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可以是字符串,导入该字符串
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 patterns(prefix, *args):#返回列表
warnings.warn(
'django.conf.urls.patterns() is deprecated and will be removed in '
'Django 1.10. Update your urlpatterns to be a list of '
'django.conf.urls.url() instances instead.',
RemovedInDjango110Warning, stacklevel=2
)
pattern_list = []
for t in args:
if isinstance(t, (list, tuple)):
t = url(prefix=prefix, *t)
elif isinstance(t, RegexURLPattern):
t.add_prefix(prefix)
pattern_list.append(t)
return pattern_list def url(regex, view, kwargs=None, name=None, prefix=''):
if isinstance(view, (list, tuple)):#返回RegexURLResolver对象
# For include(...) processing.
urlconf_module, app_name, namespace = view
return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
else:
if isinstance(view, six.string_types):
warnings.warn(
'Support for string view arguments to url() is deprecated and '
'will be removed in Django 1.10 (got %s). Pass the callable '
'instead.' % view,
RemovedInDjango110Warning, stacklevel=2
)
if not view:
raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex)
if prefix:
view = prefix + '.' + view
return RegexURLPattern(regex, view, kwargs, name)#返回RegexURLPattern
class RegexURLResolver(LocaleRegexProvider):
def __init__(self, regex, urlconf_name, default_kwargs=None, app_name=None, namespace=None):
print "i am regxurlresolver"
LocaleRegexProvider.__init__(self, regex)
# urlconf_name is the dotted Python path to the module defining
# urlpatterns. It may also be an object with an urlpatterns attribute
# or urlpatterns itself.
self.urlconf_name = urlconf_name
self.callback = None
self.default_kwargs = default_kwargs or {}
self.namespace = namespace
self.app_name = app_name
self._reverse_dict = {}
self._namespace_dict = {}
self._app_dict = {}
# set of dotted paths to all functions and classes that are used in
# urlpatterns
self._callback_strs = set()
self._populated = False def __repr__(self):
if isinstance(self.urlconf_name, list) and len(self.urlconf_name):
# Don't bother to output the whole list, it can be huge
urlconf_repr = '<%s list>' % self.urlconf_name[0].__class__.__name__
else:
urlconf_repr = repr(self.urlconf_name)
return str('<%s %s (%s:%s) %s>') % (
self.__class__.__name__, urlconf_repr, self.app_name,
self.namespace, self.regex.pattern) def _populate(self):#初始化时会递归调用
lookups = MultiValueDict()
namespaces = {}
apps = {}
language_code = get_language()
for pattern in reversed(self.url_patterns):#urls.py的urlpattern
if hasattr(pattern, '_callback_str'):#回调字符串集可以用来判断是否可回调
self._callback_strs.add(pattern._callback_str)
elif hasattr(pattern, '_callback'):#回调对象转换为字符串
callback = pattern._callback
if isinstance(callback, functools.partial):
callback = callback.func if not hasattr(callback, '__name__'):
lookup_str = callback.__module__ + "." + callback.__class__.__name__
else:
lookup_str = callback.__module__ + "." + callback.__name__
self._callback_strs.add(lookup_str)
p_pattern = pattern.regex.pattern#取得 RegexURLPattern对象的正则
if p_pattern.startswith('^'):
p_pattern = p_pattern[1:]
if isinstance(pattern, RegexURLResolver):
if pattern.namespace:
namespaces[pattern.namespace] = (p_pattern, pattern)
if pattern.app_name:
apps.setdefault(pattern.app_name, []).append(pattern.namespace)
else:
parent_pat = pattern.regex.pattern#取得模式字符串
for name in pattern.reverse_dict:#会使得RegexURLResolver对象_populate()
for matches, pat, defaults in pattern.reverse_dict.getlist(name):
new_matches = normalize(parent_pat + pat)#完善该名字对应的内容
lookups.appendlist(
name,
(
new_matches,
p_pattern + pat,
dict(defaults, **pattern.default_kwargs),
)
)
for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items():
namespaces[namespace] = (p_pattern + prefix, sub_pattern)
for app_name, namespace_list in pattern.app_dict.items():
apps.setdefault(app_name, []).extend(namespace_list)
self._callback_strs.update(pattern._callback_strs)
else:
bits = normalize(p_pattern)
lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args))
if pattern.name is not None:
lookups.appendlist(pattern.name, (bits, p_pattern, pattern.default_args)) self._reverse_dict[language_code] = lookups
self._namespace_dict[language_code] = namespaces
self._app_dict[language_code] = apps
self._populated = True

第一次查找视图函数时,会调用_populate,这样会使得各个urls.py模板都解决。

mezzanine的urlresolver

In [27]: url.__dict__
Out[27]:
{'_app_dict': {u'en': {'admin': ['admin']}},
 '_callback_strs': {u'django.contrib.auth.admin.user_change_password',
  u'django.contrib.auth.views.password_reset',
  u'django.contrib.auth.views.password_reset_complete',
  u'django.contrib.auth.views.password_reset_confirm',
  u'django.contrib.auth.views.password_reset_done',
  u'django.contrib.sitemaps.views.sitemap',
  u'django.views.i18n.javascript_catalog',
  u'filebrowser_safe.decorators.decorator',
  u'filebrowser_safe.views._check_file',
  u'filebrowser_safe.views.browse',
  u'filebrowser_safe.views.delete',
  u'filebrowser_safe.views.mkdir',
  u'filebrowser_safe.views.rename',
  u'filebrowser_safe.views.upload',
  u'mezzanine.blog.views.blog_post_detail',
  u'mezzanine.blog.views.blog_post_feed',
  u'mezzanine.blog.views.blog_post_list',
  u'mezzanine.boot.lazy_admin.<lambda>',
  u'mezzanine.core.views.direct_to_template',
  u'mezzanine.core.views.displayable_links_js',
  u'mezzanine.core.views.edit',
  u'mezzanine.core.views.search',
  u'mezzanine.core.views.set_device',
  u'mezzanine.core.views.set_site',
  u'mezzanine.core.views.static_proxy',
  u'mezzanine.generic.views.admin_keywords_submit',
  u'mezzanine.generic.views.comment',
  u'mezzanine.generic.views.rating',
  u'mezzanine.pages.views.admin_page_ordering',
  u'mezzanine.pages.views.page'},
 '_namespace_dict': {u'en': {'admin': (u'admin/',
    <RegexURLResolver <RegexURLPattern list> (admin:admin) >)}},
 '_populated': True,
 '_regex': u'^/',
 '_regex_dict': {},
 '_reverse_dict': {u'en': <MultiValueDict: {u'comment': [([(u'comment/', [])], u
'comment/$', {})], u'rating': [([(u'rating/', [])], u'rating/$', {})], u'admin_k
eywords_submit': [([(u'admin_keywords_submit/', [])], u'admin_keywords_submit/$'
, {})], <function comment at 0x035C8830>: [([(u'comment/', [])], u'comment/$', {
})], u'fb_rename': [([(u'admin/media-library/rename/', [])], u'admin/media-libra
ry/rename/$', {})], u'blog_post_list_month': [([(u'blog/archive/%(year)s/%(month
)s/', [u'year', u'month'])], u'blog/archive/(?P<year>\\d{4})/(?P<month>\\d{1,2})
/$', {})], u'fb_mkdir': [([(u'admin/media-library/mkdir/', [])], u'admin/media-l
ibrary/mkdir/', {})], u'blog_post_list_author': [([(u'blog/author/%(username)s/'
, [u'username'])], u'blog/author/(?P<username>.*)/$', {})], u'set_device': [([(u
'set_device/%(device)s/', [u'device'])], u'set_device/(?P<device>.*)/$', {})], u
'blog_post_list_category': [([(u'blog/category/%(category)s/', [u'category'])],
u'blog/category/(?P<category>.*)/$', {})], <function _check_file at 0x035EA530>:
 [([(u'admin/media-library/check_file/', [])], u'admin/media-library/check_file/
$', {})], <function static_proxy at 0x035B0130>: [([(u'asset_proxy/', [])], u'as
set_proxy/$', {})], <function user_change_password at 0x035EA930>: [([(u'admin/a
uth/user/%(_0)s/password/', [u'_0'])], u'admin/auth/user/(\\d+)/password/$', {})
], u'blog_post_detail_day': [([(u'blog/%(year)s/%(month)s/%(day)s/%(slug)s/', [u
'year', u'month', u'day', u'slug'])], u'blog/(?P<year>\\d{4})/(?P<month>\\d{1,2}
)/(?P<day>\\d{1,2})/(?P<slug>.*)/$', {})], u'home': [([(u'', [])], u'$', {u'temp
late': u'index.html'})], u'displayable_links_js': [([(u'displayable_links.js', [
])], u'displayable_links.js$', {})], <function blog_post_list at 0x035C89B0>: [(
[(u'blog/', [])], u'blog/$', {}), ([(u'blog/archive/%(year)s/', [u'year'])], u'b
log/archive/(?P<year>\\d{4})/$', {}), ([(u'blog/archive/%(year)s/%(month)s/', [u
'year', u'month'])], u'blog/archive/(?P<year>\\d{4})/(?P<month>\\d{1,2})/$', {})
, ([(u'blog/author/%(username)s/', [u'username'])], u'blog/author/(?P<username>.
*)/$', {}), ([(u'blog/category/%(category)s/', [u'category'])], u'blog/category/
(?P<category>.*)/$', {}), ([(u'blog/tag/%(tag)s/', [u'tag'])], u'blog/tag/(?P<ta
g>.*)/$', {})], <function rename at 0x035EA8B0>: [([(u'admin/media-library/renam
e/', [])], u'admin/media-library/rename/$', {})], <function blog_post_detail at
0x0361B770>: [([(u'blog/%(slug)s/', [u'slug'])], u'blog/(?P<slug>.*)/$', {}), ([
(u'blog/%(year)s/%(slug)s/', [u'year', u'slug'])], u'blog/(?P<year>\\d{4})/(?P<s
lug>.*)/$', {}), ([(u'blog/%(year)s/%(month)s/%(slug)s/', [u'year', u'month', u'
slug'])], u'blog/(?P<year>\\d{4})/(?P<month>\\d{1,2})/(?P<slug>.*)/$', {}), ([(u
'blog/%(year)s/%(month)s/%(day)s/%(slug)s/', [u'year', u'month', u'day', u'slug'
])], u'blog/(?P<year>\\d{4})/(?P<month>\\d{1,2})/(?P<day>\\d{1,2})/(?P<slug>.*)/
$', {})], <function direct_to_template at 0x035B0270>: [([(u'', [])], u'$', {u't
emplate': u'index.html'})], <function rating at 0x035C8870>: [([(u'rating/', [])
], u'rating/$', {})], u'blog_post_detail': [([(u'blog/%(slug)s/', [u'slug'])], u
'blog/(?P<slug>.*)/$', {})], <function displayable_links_js at 0x035B0330>: [([(
u'displayable_links.js', [])], u'displayable_links.js$', {})], <function sitemap
 at 0x035EAB70>: [([(u'sitemap.xml', [])], u'sitemap\\.xml$', {u'sitemaps': {u'a
ll': <class 'mezzanine.core.sitemaps.DisplayableSitemap'>}})], <function mkdir a
t 0x035EA3F0>: [([(u'admin/media-library/mkdir/', [])], u'admin/media-library/mk
dir/', {})], <function search at 0x035B03B0>: [([(u'search/', [])], u'search/$',
 {})], u'blog_post_detail_year': [([(u'blog/%(year)s/%(slug)s/', [u'year', u'slu
g'])], u'blog/(?P<year>\\d{4})/(?P<slug>.*)/$', {})], u'blog_post_list_tag': [([
(u'blog/tag/%(tag)s/', [u'tag'])], u'blog/tag/(?P<tag>.*)/$', {})], u'user_chang
e_password': [([(u'admin/auth/user/%(_0)s/password/', [u'_0'])], u'admin/auth/us
er/(\\d+)/password/$', {})], u'blog_post_list': [([(u'blog/', [])], u'blog/$', {
})], u'blog_post_feed_tag': [([(u'blog/tag/%(tag)s/feeds/%(format)s/', [u'tag',
u'format'])], u'blog/tag/(?P<tag>.*)/feeds/(?P<format>.*)/$', {})], <function bl
og_post_feed at 0x0361BC70>: [([(u'blog/author/%(username)s/feeds/%(format)s/',
[u'username', u'format'])], u'blog/author/(?P<username>.*)/feeds/(?P<format>.*)/
$', {}), ([(u'blog/category/%(category)s/feeds/%(format)s/', [u'category', u'for
mat'])], u'blog/category/(?P<category>.*)/feeds/(?P<format>.*)/$', {}), ([(u'blo
g/tag/%(tag)s/feeds/%(format)s/', [u'tag', u'format'])], u'blog/tag/(?P<tag>.*)/
feeds/(?P<format>.*)/$', {}), ([(u'blog/feeds/%(format)s/', [u'format'])], u'blo
g/feeds/(?P<format>.*)/$', {})], u'fb_browse': [([(u'admin/media-library/browse/
', [])], u'admin/media-library/browse/$', {})], <function admin_keywords_submit
at 0x035C87F0>: [([(u'admin_keywords_submit/', [])], u'admin_keywords_submit/$',
 {})], u'blog_post_feed_author': [([(u'blog/author/%(username)s/feeds/%(format)s
/', [u'username', u'format'])], u'blog/author/(?P<username>.*)/feeds/(?P<format>
.*)/$', {})], u'blog_post_feed_category': [([(u'blog/category/%(category)s/feeds
/%(format)s/', [u'category', u'format'])], u'blog/category/(?P<category>.*)/feed
s/(?P<format>.*)/$', {})], u'search': [([(u'search/', [])], u'search/$', {})], <
function page at 0x02A92CF0>: [([(u'%(slug)s/', [u'slug'])], u'(?P<slug>.*)/$',
{})], <function set_device at 0x035B00B0>: [([(u'set_device/%(device)s/', [u'dev
ice'])], u'set_device/(?P<device>.*)/$', {})], u'password_reset_done': [([(u'pas
sword_reset/done/', [])], u'password_reset/done/$', {})], u'fb_check': [([(u'adm
in/media-library/check_file/', [])], u'admin/media-library/check_file/$', {})],
<function admin_page_ordering at 0x02A92D30>: [([(u'admin_page_ordering/', [])],
 u'admin_page_ordering/$', {})], u'fb_upload': [([(u'admin/media-library/upload/
', [])], u'admin/media-library/upload/', {})], u'blog_post_detail_month': [([(u'
blog/%(year)s/%(month)s/%(slug)s/', [u'year', u'month', u'slug'])], u'blog/(?P<y
ear>\\d{4})/(?P<month>\\d{1,2})/(?P<slug>.*)/$', {})], <function browse at 0x035
EA2F0>: [([(u'admin/media-library/browse/', [])], u'admin/media-library/browse/$
', {})], u'static_proxy': [([(u'asset_proxy/', [])], u'asset_proxy/$', {})], <fu
nction upload at 0x035EA4F0>: [([(u'admin/media-library/upload/', [])], u'admin/
media-library/upload/', {})], <function delete at 0x035EA7B0>: [([(u'admin/media
-library/delete/', [])], u'admin/media-library/delete/$', {})], <function passwo
rd_reset at 0x02A925F0>: [([(u'password_reset/', [])], u'password_reset/$', {})]
, <function set_site at 0x035B0030>: [([(u'set_site/', [])], u'set_site/$', {})]
, u'password_reset_complete': [([(u'reset/done/', [])], u'reset/done/$', {})], <
function edit at 0x035B0430>: [([(u'edit/', [])], u'edit/$', {})], u'blog_post_l
ist_year': [([(u'blog/archive/%(year)s/', [u'year'])], u'blog/archive/(?P<year>\
\d{4})/$', {})], <function javascript_catalog at 0x03571870>: [([(u'jsi18n/%(pac
kages)s/', [u'packages'])], u'jsi18n/(?P<packages>\\S+?)/$', {u'domain': u'djang
o'})], <function password_reset_done at 0x02A92670>: [([(u'password_reset/done/'
, [])], u'password_reset/done/$', {})], u'edit': [([(u'edit/', [])], u'edit/$',
{})], u'password_reset_confirm': [([(u'reset/%(uidb64)s/%(token)s/', [u'uidb64',
 u'token'])], u'reset/(?P<uidb64>[0-9A-Za-z_\\-]+)/(?P<token>.+)/$', {})], <func
tion decorator at 0x035EA670>: [([(u'admin/media-library/upload_file/', [])], u'
admin/media-library/upload_file/$', {})], u'fb_do_upload': [([(u'admin/media-lib
rary/upload_file/', [])], u'admin/media-library/upload_file/$', {})], u'fb_delet
e': [([(u'admin/media-library/delete/', [])], u'admin/media-library/delete/$', {
})], <function <lambda> at 0x035B06F0>: [([(u'admin/media-library/', [])], u'adm
in/media-library/$', {})], u'password_reset': [([(u'password_reset/', [])], u'pa
ssword_reset/$', {})], u'media-library': [([(u'admin/media-library/', [])], u'ad
min/media-library/$', {})], u'blog_post_feed': [([(u'blog/feeds/%(format)s/', [u
'format'])], u'blog/feeds/(?P<format>.*)/$', {})], u'admin_page_ordering': [([(u
'admin_page_ordering/', [])], u'admin_page_ordering/$', {})], u'set_site': [([(u
'set_site/', [])], u'set_site/$', {})], <function password_reset_confirm at 0x02
A927B0>: [([(u'reset/%(uidb64)s/%(token)s/', [u'uidb64', u'token'])], u'reset/(?
P<uidb64>[0-9A-Za-z_\\-]+)/(?P<token>.+)/$', {})], u'page': [([(u'%(slug)s/', [u
'slug'])], u'(?P<slug>.*)/$', {})], <function password_reset_complete at 0x02A92
7F0>: [([(u'reset/done/', [])], u'reset/done/$', {})]}>},
 'app_name': None,
 'callback': None,
 'default_kwargs': {},
 'namespace': None,
 'url_patterns': [<RegexURLResolver <RegexURLPattern list> (None:None) ^admin/>,

<RegexURLPattern home ^$>,
  <RegexURLResolver <module 'mezzanine.urls' from 'c:\python27\lib\site-packages
\mezzanine\urls.pyc'> (None:None) ^>],
 'urlconf_module': <module 'mez.urls' from 'C:\mez\mez\urls.pyc'>,
 'urlconf_name': u'mez.urls'}

django之urlresolver的更多相关文章

  1. Django 源码小剖: URL 调度器(URL dispatcher)

    在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 URL. 这是 django url 匹配处理机制的 ...

  2. URL 调度器(URL dispatcher)

    URL 调度器(URL dispatcher) 在刚开始接触 django 的时候, 我们尝试着从各种入门文档中创建一个自己的 django 项目, 需要在 mysite.urls.py 中配置 UR ...

  3. Django学习之十一:真正理解Django的路由分发和反解url原理

    目录 URL Dispatcher 简介 模式概念 对比URLPattern 与 URLResolver (多态的体现) 构建子路由几种方式 反解url算法逻辑 URL Dispatcher 简介 d ...

  4. Django学习之七:Django 中间件

    目录 Django 中间件 自定义中间件 - - - 大体两种方式 将中间件移除 实例 中间件加载源码阅读 总结 Django 中间件 Tips: 更新日志: 2019.01.31 更新django中 ...

  5. Django学习笔记之URL与视图

    视图 视图一般都写在app的views.py中.并且视图的第一个参数永远都是request(一个HttpRequest)对象.这个对象存储了这个http请求的所有信息,其中包括携带的参数以及一些头部信 ...

  6. Django自动获取项目中的全部URL

    import re from collections import OrderedDict from django.conf import settings from django.utils.mod ...

  7. Django url分发器

    视图: 视图一般都写在app的views.py中.并且视图的第一个参数永远都是request(一个HttpRequest)对象.这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等.在视 ...

  8. Django(二):url和views

    网络通讯的本质是socket,从socket封装到MVC模式,参见另外几篇博客.本节笔记整理自Django2.0官方文档. 一.url调度器 - django.urls.path django2.0中 ...

  9. Django REST framework完全入门

    Django REST framework 一个强大灵活的Django工具包,提供了便捷的 REST API 开发框架 我们用传统的django也可以实现REST风格的api,但是顶不住Django ...

随机推荐

  1. SpringBoot集成RabbitMQ

    官方说明:http://www.rabbitmq.com/getstarted.html 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.MQ ...

  2. VUEX 学习

    语法   翻译  功能介绍 module(模块)extend(扩展)extract(提取)export(输出)router(路由器)components(组件) store(储存)state (声明. ...

  3. c语言中printf()函数中的参数计算顺序

    今天看到了一个关于printf()函数计算顺序的问题,首先看一个例子: #include<stdio.h> int main() { printf("%d---%d---%d&q ...

  4. Jenkins XVnc Plugin

    Linux下的Jenkins里配置Webdriver项目会碰到如下错误 org.openqa.selenium.firefox.NotConnectedException: Unable to con ...

  5. spring 如何决定使用jdk动态代理和cglib(转)

    Spring1.2: 将事务代理工厂[TransactionProxyFactoryBean] 或 自动代理拦截器[BeanNameAutoProxyCreator] 的 proxyTargetCla ...

  6. OpenStack存储(单节点)

    一.OpenStack Swift对象存储 1.安装Swift服务 在controller节点依次执行iaas-install-swift-controller.sh和iaas-install-swi ...

  7. NFS应用场景及环境搭建

    两台虚拟机,一台做服务端(server)用来存储,一台做客户端(client)用来访问. 注意,两台虚拟机都已经挂载完光盘,并配置好yum源.客户端client已经安装好lamp环境,服务端不做任何处 ...

  8. PyCharm的一些设置

    设置使用UTF-8 在任何情况下: 设置写python脚本,新建 脚本的时候默认加的头文件. # !/usr/bin/env python# -*- coding:utf-8 -*-# Author: ...

  9. Django的视图层简介

    Django的视图层 视图函数 所谓视图函数,其实就是我们Django项目中各个应用中的views.py文件中定义的每个用来处理URL路由映射到这里的逻辑函数.一个视图函数简称视图,它是个简单的Pyt ...

  10. Bootstrap的简介及使用

    一.Bootstrap简介 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.javascript 的,它简洁灵活,使得 Web 开发更 ...