Django基础-Web框架-URL路由

Django基础-Web框架-URL路由

一、Django基础–Web框架

MVC和MTV框架

MVC

把Web应用分为模型(M)、视图(V)、控制器(C)三层,他们之间以一种插件式的,松耦合的方式联系在一起。模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接收用户的输入调用模型和视图完成用户的请求。
Django基础-Web框架-URL路由_第1张图片

MTV

Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:

  • M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
  • T 代表模板 (Template):负责如何把页面展示给用户(html)。
  • V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。

除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:

一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。

Django下载与安装

  1. Dango下载
  • 命令行
    • pip install Django: 最新版本
    • pip install -i pypi.tuna.tsinghua.edu.cn/simple django==1.11.28 (指定版本)
  • 在pycharm中下载(和下载第三方一样)

2.创建项目

  • 命令行
    • Django-admin startproject 项目名称
  • pycharm
    • File à new project -> 左侧选择django ->选择目录 ->选择解释器->create按钮

3.目录介绍

  • Settings.py:
    • BASE_DIR:项目的根目录
    • DEBUG=true: 当前是调试模式
      如果DEBUG=False ALLOWED_HOSTS=[“*”] 表示所的用户可以访问
    • TEMPLATES=[ “DIRS”:当前文件的地址] :模板
    • ‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)]:指定当前目录的文件夹。
      Templates
      *文件夹是存放html***文件的

4.运行Django项目

  • 命令行
    • python manage.py runserver #默认启动127.0.0.1:8000
    • python manage.py runserver 80 #更改默认端口127.0.0.1:80
    • python manage.py runserver 0.0.0.0:80 #更改Ip和端口
  • pycharm
    • 不能用右键点击,直接选择项目,点绿三角

5.Django简单示例

  1. URL控制器

    from App import views

    urlpatterns = [
    url(r’^admin/’, admin.site.urls),
    url(r"^login/$", views.login, name=“login”) # 对应到views视图,name是一个别名
    ]

  2. 在templates模板里写html

    {% csrf_token %}

    欢迎来到我的博客

    请输入用户名
    请输入密码
  3. views视图

    def login(request):
    if request.method == “POST”:
    user = request.POST.get(“user”)
    password = request.POST.get(“password”)
    user_obj = models.User.objects.filter(username=user, password=password)
    if user_obj:
    return render(request, “index.html”)
    return render(request, “login.html”)

  4. 直接访问本地http://127.0.0.1:8000/login/

    1.创建项目
    2.创建app
    3.url.py
    4.templates
    5.views.py

  5. get,post请求

  6. get请求获取数据

    Get请求通常没有请求体,会放到url中

  7. post请求获取数据

    POST获取数数会进行安全检验(跨站请求),为了避免有三种方法

    1. 在form中添加 {% csrf_token %}

      {% csrf_token %}
    2. 在form中添加novalidate属性(表示不进行格式验证)

    3. 在settings.py中注释中间键
      MIDDLEWARE = [ #中间键

      ‘django.middleware.csrf.CsrfViewMiddleware’, 注释掉了可以提交POST请求

      ]

登录页面-静态文件的引入

主是要在settings.py中设置STATIC_URL,STATICFILES_DIRS

配置settings.py:

#重要的是settings.py文件的设置(表示找到static文件)
STATIC_URL = '/static/' #静态文件的别名(static是可以修改的)指的是引入文件
#  STATIC_URL里面的static是和引入文件对应的!!!!如果这里是xx那src="/xx/images/1.jpg
STATICFILES_DIRS=[
    os.path.join(BASE_DIR,'static'),# 指的是创建的文件夹static,可以有1个或多个(和下面创建的相对应的)
    os.path.join(BASE_DIR,'static1')
]

步骤: 1.先在bootcss.com网站找到对应的框架,2.把里面需要的内容copy过来 3.下载对应的css文件。4.创建static文件夹 5.在settings.py里面编写对应文件夹的位置 STATICFILES_DIRS=[ os.path.join(BASE_DIR,‘static’) 6.写html ]

实例操作

  1. 在项目文件夹下建立一个文件夹存放静态文件,比如叫cctv
  2. 在cctv文件夹下再建立一个css文件夹
  3. 在css文件夹下建立一个das.css文件

在settings.py文件下写入

STATIC_URL = '/static/' # 别名,一般都起static
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'cctv'),
]

  	{% load static %}
	{#这样写了不用管STATIC_URL = '/static/' 叫什么名称了  会自己识别#}
    
    

STATIC_URL = '/xxx/' 都可以自动识别

{% get_static_prefix %}  这个是就识别当前的 STATIC_URL = '/xxx/ 名字  返回它的名字/xxx/
所有以可以这样写:

app的创建和注册

创建app:

  1. 命令行:
    • python manage.py startapp startapp(名称)
  2. 通过 run manage.py task
    • tools -> run manage.py task -> 出现窗口 输入命令即可 startapp startapp(名称)

此时新建了一个应用文件startapp,它的里面也创建了一些py文件和包:

migrations : 用于在之后定义引用迁移功能。

admin.py :管理站点模型的声明文件,默认为空。

apps.py :应用信息定义文件。在其中生成了类Appconfig,类用于定义应用名等Meta数据。app

models.py : 添加模型层数据类的文件。ORM

test.py :测试代码文件。

views.py :定义URL响应函数。 函数

注册:

在settings.py文件里面注册:

INSTALLED_APPS = [
  	。。。。
    'app01', # 直接写app的名称
    'app01.apps.App01Config' # 推荐写法
]

二、Django基础–URL路由

路由

from django.conf.urls import url

urlpatterns = {  #Django2.0了这里这是path,也可以在settings.py里面查看版本信息
	url(正则表达式,views视图,参数,别名), 
}
  • 正则表达式:一个正则表达式字符串
  • views视图:一个可调用对象,通常为一个视图函数
  • 参数:可选的要传递给视图函数的默认参数(字典形式)
  • 别名:一个可选的name参数

正则表达式

r'^articles/2003/'

r:原生字符串
^:以什么开头
$:以什么结尾
\d:数字  {}:几个数字范围   \w:字母  [0-9][a-z] :0到9的数字和a到z的字符
. 匹配换行符之外的标志
+一个或多个
?0个或1个
*0个或多个

注意事项

  1. urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。

  2. 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。

  3. 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。

  4. 每个正则表达式前面的’r’ 是可选的但是建议加上。

    urlpatterns = [
    url(r’^admin/’, admin.site.urls),
    url(r’^blog/KaTeX parse error: Expected 'EOF', got '#' at position 22: …ws.blog), #̲ blogs/2012/12/…’, views.blogs), #如果不写 的 时 候 , 我 们 访 问 b l o g / 2002 就 会 被 b l o g 给 截 胡 了 , 因 为 是 从 上 向 下 查 找 的 u r l ( r ′ b l o g s / [ 0 − 9 ] 4 / 的时候,我们访问blog/2002就会被blog给截胡了,因为是从上向下查找的 url(r'^blogs/[0-9]{4}/ 访blog/2002blogurl(rblogs/[09]4/’, views.blogs), # blogs/2012/
    ]

    是否开启URL访问地址后面不为/跳转至带有/的路径的配置项

    APPEND_SLASH=True #就是设置这个为False了django就不会默认加‘/’这个了

    DEBUG = False 为True表示的是测试环境,上线的是时候要改成这样

    ALLOWED_HOSTS = ["*"]

分组

url地址上捕获的参数会按照 位置传参 方式传递给视图函数

位置传参:()
url(r'^blogs/([0-9]{4})/(\d{2})/$', views.blogs),  
url(r'^blogs/([0-9]{4})/$', views.blogs), # blogs/2012/

    # views.py
def blogs(request,x,y): #一个括号,表示一个参数(位置传参),接送匹配到的数据
	print(x,type(x))
	print(y,type(y))
    return HttpResponse("blogs")

命名分组

url地址上捕获的参数会按照 关键字传参 方式传递给视图函数

关键字传参:(?P<名称>) (?P<名称>)
    url(r'^blogs/(?P[0-9]{4})/(?P\d{2})/$', views.blogs), 
    
def blogs(request,year,month): # 这里的名称一定要和关键字对应
    print(year,type(year))
    print(month,type(month))
    return HttpResponse("blogs")
    
def blogs(request,*args,**kwargs): #元组,和字典,这样也可以
	print(args)
    print(kwargs)

分组和命名分组,不能混合用。捕获的参数永远都是字符串

视图函数中指定默认值

# urls.py中
urlpatterns = [
    url(r'^blog/$', views.page),  #没有捕获取到东西的话,将会使用默认值 num=1
    url(r'^blog/page(?P[0-9]+)/$', views.page),
]

# views.py中,可以为num指定默认值
def page(request, num="1"):
    pass;)

在上面的例子中,两个URL模式指向相同的view - views.page - 但是第一个模式并没有从URL中捕获任何东西。

如果第一个模式匹配上了,page()函数将使用其默认参数num=“1”,如果第二个模式匹配,page()将使用正则表达式捕获到的num值。

传递额外的参数给视图函数

url(r'^blogs/([0-9]{4})/$', views.blogs,{"k1":"v1"}), # blogs/2012/

def blogs(request,*args,**kwargs):
    print(args)  #('2012',)
    print(kwargs)   #{'k1': 'v1'}
    return HttpResponse("blogs")

include路由分发

  1. 在app下重新创建一个urls.py

    from django.conf.urls import url
    from app01 import views

    urlpatterns = [
    url(r’^blog/ ′ , v i e w s . b l o g ) , u r l ( r ′ b l o g s / ( [ 0 − 9 ] 4 ) / ', views.blog), url(r'^blogs/([0-9]{4})/ ,views.blog),url(rblogs/([09]4)/’, views.blogs,{“k1”:“v1”}), # blogs/2012/
    ]

  2. 改原本项目下的urls.py里面的内容加上include

    from django.conf.urls import url,include
    from django.contrib import admin

    urlpatterns = [
    url(r’^admin/’, admin.site.urls),
    # url(r’^app01/’, include(“app01.urls”)),# http://127.0.0.1:8000/app01/blogs/2002/
    url(r’^’, include(“app01.urls”)),# http://127.0.0.1:8000/blog/ 如果为空的话
    ]

里面参数可以为空(其实就是把原来urls.py里面的参数封装到app下,让在用include()调用app下的urls.py)的内容

url的命名和反向解析

其实就是和函数中的as一样 设置一个别名

静态路由

命名:name=""

url(r'^blogs/$', views.blogs, name="bloogs"),  # 设置一个别名 bloogs

反向解析: 模板 生成的地址

测试url的命名和反向解析     --> blogs - bloogs 获取的就是blogs  
其实就是访问了别名为bloogs对应的url

py

from django.shortcuts import reverse  #有两种导入的方法
from django.urls import reverse

print(reverse("bloogs"))  #/blogs/

动态路由

  1. 分组:

     url(r'^blogs/([0-9]{4})/(\d{2})$', views.blogs, name="bloogs"),
    

    反向解析:模板

    测试url的命名和反向解析
    #要给上参数,还要参数对应,不然就会出错.其实就是访问了别名为bloogs对应的url

    py

    print(reverse(“bloogs”,args=(2002,99))) # /blogs/2002/99

  2. 命名分组

     url(r'^blogs/(?P[0-9]{4})/(?P\d{2})$', views.blogs, name="bloogs"),
    

    反向解析:模板

    {#测试url的命名和反向解析#} #这个要对应参数
    测试url的命名和反向解析 #这个不用对应参数
    其实就是访问了别名为bloogs对应的url

    py

    print(reverse(“bloogs”,args=(2002,99))) # /blogs/2002/99
    print(reverse(“bloogs”,kwargs={“year”:“2009”,“method”:99})) # /blogs/2009/9

命名空间 namespace

app01 urls.py:

urlpatterns = [
    url(r'^home/$', views.home, name='home')
]


app02 urls.py:
urlpatterns = [
    url(r'^home/$', views.home, name='home')
]

#app01和app02我们写了一样的别名
#我们用app01调用html的时候{% url 'home' %},app02的home会覆盖了app01里面的home

为了避免以上操作:我们就要加namespace

# 在项目的urls.py下
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app01/', include("app01.urls", namespace="app01")),
    url(r'^app02/', include("app02.urls", namespace="app02")),
]

光加了命名空间,也不行。我们在用反向解析和py的时候,也要在对应的地方区分并添加

反向解析:
模块
{% url 'app01:home' %}
{% url 'app02:home' %}
py
 print(reverse("app01:home"))  # /app01/home/
 print(reverse("app02:home"))  # /app02/home/

你可能感兴趣的:(Python,python,django)