Django03 - 路由控制

一:django连接MySQL与SQLite

连接MySQL

1.安装pymysql

pip3 install pymysql

2.去settings.py中配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "django_db01",
        "HOST": "127.0.0.1",
        "PORT": 3306,
        "USER": "root",
        "PASSWORD": "123456",
    }
}

3.用pymysql替换原来的mysqldb

到项目/app的__init__.py中或者settings.pyDATABASES后输入
import pymysql

pymysql.install_as_MySQLdb()

4.然后执行数据迁移命令

捷径步骤1:Tools - Run manage.py Task...

捷径步骤2:直接输入下方语句
  • makemigrations - 生成数据迁移文件
  • migrate - 执行数据迁移,同步到数据库
  • showmigrations - 查看哪些记录已经同步到数据库中:[ ] - 未同步, [ × ] - 已同步

连接SQLite

也是一个数据库,文件数据库,一个可以就是一个文件,不需要单独安装

常用于移动开发本地存储数据,存在sqlite中

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

二:pycharm操作sqlite和mysql

JetBrains的全系列产品都内置了Data Grip(类似于Navicat的操作数据库的客户端),PyCharm也不例外。

具体操作:

填入数据进行连接

测试连接成功

鼠标点击即可操作

三:路由层之简单路由配置

1.路由参数

实例:

url(r'^index/', views.index,{'name':'Darker','age':18},name='index'),

① 参数1 - regex

上述的第2个部分r'^index/',用于填写正则表达式

此处常用正则:

^ - 以...开头

$ - 以...结尾

如果是r'^$',那么一开始就会进入这个对应的页面

② 参数2 - view

上述的第2个部分views.index,用于填写对应的视图

③ 参数3 - kwargs

上述的第3个部分是一个字典{'name':'Darker','age':18},用于给对应的视图传参

def index(request,name,age):
	...

和之后的反向解析一起用的话,位置参数在前,关键字参数在后。

④ 参数4 - name

述的第4个部分name='index',用于反向解析

四:路由层之APPEND_SLASH

1.作用

如果用户忘记加/,可以给URL自动加上/后缀进行匹配

APPEND_SLASH默认开启

2.验证

APPEND_SLASH开启的情况下

urls.py

url(r'^index/$', views.index),

末尾不加/ - 会发送2次请求,还有1次是重定向

重定向示意图

末尾加/ - 会发送1次请求

APPEND_SLASH关闭的情况下

3.关闭APPEND_SLASH

settings.py中添加下方代码
APPEND_SLASH = False

五:有名分组 无名分组

1.无名分组

无名分组,把分组分出来的值,当作位置参数传递给视图函数

Python中示例:

import re

res = re.search('([0-9]{4})/([0-9]{2})', '2018/12')

print(res.group(1))     # 2018
print(res.group(2))     # 12

urls.py

url(r'^index/([0-9]{4})/([0-9]{2})', views.index),

views.py

def index(request, a, b):
    print(a, b)
    return render(request, 'index.html')

2.有名分组

有名分组,把分组出来的值,当作关键字参数传递给视图函数

Python中示例:

import re

res = re.search('(?P<year>[0-9]{4})/(?P<month>[0-9]{2})', '2018/12')

print(res.group('year'))        # 2018
print(res.group('month'))       # 12

urls.py

url(r'^index/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})', views.index),

views.py

def index(request, a, b):
    print(a, b)
    return render(request, 'index.html')

3.作用

可以从url地址中解析出参数传递给视图函数使用

4.案例

以博客园的某篇文章为例:

image-20200930075832213

其中:

https是协议

www.cnblogs.com是域名

xuexianqi是用户名称

p是页面

12767075是文章id

.html代表这篇文章是一个静态的页面(也有可能是伪静态)

无名分组:

url(r'^(.*?)/p/(\d+).html', views.index),

有名分组:

url(r'^(?P<name>.*?)/p/(?P<id>\d+).html', views.index),

有名分组和无名分组不能混合使用

5.伪静态

页面分2种:

1种是动态的:http://www.xuexianqi.top/archives/136 (该地址已失效)

1种是静态的:http://www.xuexianqi.top/archives/136.html

伪静态,就是把动态的页面伪装成一个静态的页面(比如说在结尾加上:.html),便于SEO优化

我是如何实现伪静态的:http://www.xuexianqi.top/archives/294.html

什么是SEO:http://www.xuexianqi.top/archives/367.html

六:路由分发

1.什么是路由分发?

在django项目中,可以创建许多个app,如果把每个app的路由都写在一个urls.py中,代码的耦合度会很高,如果一个页面中,路由过多,会出现一些混乱。

于是,就出现了路由分发的概念:每个app拥有自己独立的urls.py,然后在总路由中添加每个app的urls.py的路径,做一个分发的处理。

这样一来,就会识别当前url属于哪个app,直接分发给对应的app去处理

2.如何使用路由分发?

总路由

from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 1.路由分发 - 方法1
    url(r'^app01/',include(app01_urls)),  # 只要url前缀是app01开头 全部交给app01处理
    url(r'^app02/',include(app02_urls))   # 只要url前缀是app02开头 全部交给app02处理
  
    # 2.路由分发 - 方法2
    url(r'^app01/',include('app01.urls')),
    url(r'^app02/',include('app02.urls'))
    # 注意事项:总路由里面的url千万不能加$结尾
]

子路由

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

  urlpatterns = [
      url(r'^reg/',views.reg)
  ]
  
# app02 urls.py
  from django.conf.urls import url
  from app02 import views

  urlpatterns = [
      url(r'^reg/',views.reg)
  ]

七:反向解析

1.什么是反向解析?

通过路由的别名,解析出路由的地址

动态根据路由别名获得路径,一旦路径改变,不需要改其他代码

2.如何使用反向解析?

① 在urls.py中

url(r'^index111/',views.index,name='index')

② 在视图函数中 使用反向解析

from django.shortcuts import render,HttpResponse,redirect,reverse
  	url=reverse('index')  # index就是路由的别名
    print(url)

③ 在模板文件中 使用反向解析

{% url 'index' %}

八:名称空间

1.有了反向解析,为何还需要名称空间?

路由做反向解析时,如果有同名路由,就会出现问题。

为了解决这里问题,可以在路由分发的时候,给每个app的路径设置一个名称空间

2.如何使用?

① 在总路由中设置

url(r'^app01',include('app01.urls','名称空间的名字') ),

② 用在视图函数中 使用名称空间

url=reverse('a01:index')  # index就是路由的别名
print(url)

③ 在模板文件中 使用名称空间

{% url 'a01:index' %}

九:django2.0版的path

在django2.0及以上的path

第一个参数不在是正则表达式了,而是一个具体的地址

1.2.X以后,建议使用path,第一个参数是一个准确的路径

2.如果要使用正则,推荐使用re_path,用法和1.X的url相同

十:path转化器

在django中,有5个内置转换器

str

匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式

int

匹配正整数,包含0

slug

匹配字母、数字以及横杠、下划线组成的字符串

uuid

匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00

path

匹配任何非空字符串,包含了路径分隔符(/)(不能用

实例

path('login/<int:year>', views.login),
path('login/<str:year>', views.login),
path('login/<path:p>', views.article),

实例 - 进阶

实现匹配这种路径:http://127.0.0.1:8000/xuexianqi/p/123.html
    -path('<str:name>/p/<int:id>.html', views.article),
    -re_path(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login),
    -url(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login),  # url在2.x以后不建议使用

注意

转换器 不可以在re_path中使用

十一:自定义转化器

基本步骤

regex属性:这里写的正则表达式就能匹配

to_python方法

to_url 方法

具体方法

converters.py - 编写自定义转换器

class MyConver():
    regex = '[0-9]{4}'  # 正则表达式

    # 一旦上面的正则表达式匹配成功,就会当做value的参数 传递进来
    def to_python(self, value):
        return int(value)  # 此处返回的值,会当做参数传递到视图函数

    def to_url(self, value):  # 反向解析时使用
        return '%04d' % value

urls.py - 注册自定义转换器

from .converters import MyConver
register_converter(MyConver, 'mine')

urls.py - 使用自定义转换器

path('<mine:name>/', views.index),
posted @ 2020-10-20 10:01  轻描丨淡写  阅读(198)  评论(0编辑  收藏  举报