* url映射
* 传递参数
* 应用命令空间
* 默认参数
## 昨天遇到的问题
* windows 中 用户名 不要写成中文
* 如果说 遇到 mkvirtualenv workon 命令找不到
* 将 C:\Python\Python36\Scripts (python安装目录 下面有 mkvirtualenv.bat的脚本)加到环境变量
* 所有的虚拟环境 默认创建在 用户/你的用户名/Envs 解决方案 系统变量中新建 WORKON_HOME 参数 : 新的地址 不能有中文
* 创建虚拟环境的时候 指定python路径 如果路径中 有空格 解决方案 --python=""
路径加上双引号
## url 传递参数
vim book应用下 views.py
```
from django.shortcuts import render #这个render 用来渲染模板 后期会学到
from django.http import HttpResponse
def book(request):
return HttpResponse("图书首页 多读书多看报少吃零食多睡觉")
def book_detail(request,book_id): #通过参数将book_id传递过去
text = "您要请求的图书id为:%s" % book_id
return HttpResponse(text)
def author_detail(request):
author_id = request.GET['id'] #用来接收 用户在url中传递过来的参数
text = '作者的id是:%s' % author_id
#http://127.0.0.1:9000/book/author/?id=5
return HttpResponse(text)
def book_detail(request,book_id,category_id): #传递两个参数的时候
text = "您要请求的图书id为:%s 图书类目id为: %s" % (book_id,category_id) 括号隔开
return HttpResponse(text)
```
vim 项目下 urls.py
```
from django.urls import path
from django.http import HttpResponse
from book import views
def index(request):
return HttpResponse('首页')
urlpatterns = [
path('',index),
path('book/',views.book),
path('book/detail/
path('book/author/',views.author_detail),#author没有参数
path('book/detail/
]
```
### 指定参数的类型
```
def publisher_detail(request,publisher_id):
text = '出版社的id是:%s' % publisher_id
return HttpResponse(text)
from django.urls import converters (鼠标放上去 ctrl+点击)
path('book/publisher/
path('book/publisher/
path('book/publisher/
path('book/publisher/
int 只能是一个或者多个整型数字
path 所有字符都能满足 dc9c10b6-b153-4a25-a102-44cc0e1eb5ea import uuid print(uuid.uuid4())
str 除了 /之外的都可以
slug '[-a-zA-Z0-9_]+'
当 <> 里边 不写 int str uuid 默认是 匹配str
```
## urls模块化
> 如果项目越来越大 模块越来越多 我们需要在项目主目录下 urls 添加多行 path()
>
> 每个app 自己的url 自己管理
>
> 首选 需要在 应用 中创建一个新文件 urls.py
vim book/urls.py
```
from django.urls import path
from . import views
urlpatterns = [
path('',views.book),
path('detail/
]
```
vim book/views.py
```
from django.shortcuts import render
from django.http import HttpResponse
def book(request):
return HttpResponse("图书首页")
def book_detail(request,book_id):
text = "图书id为:%s" % book_id
return HttpResponse(text)
# Create your views here.
```
vim 主目录下面的urls.py
```
from django.urls import path,include
urlpatterns = [
path('book/',include('book.urls')), #这里边 book后面加了/ app 下面的urls.py 注意不要多加/ urls是拼接起来的
]
```
## urls 命名 及 命名空间
> 为什么要给url命名
```
因为url 是经常变化的 如果在代码中写死 可能会经常该代码 给 url 起个名字 以后使用的时候 对名字进行反转 获取到修改后的url 这时候就不需要写死代码
示例代码 :
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse("后台首页")
else:
login_url = reverse('front:login')
print(login_url)
# return redirect('/signup/') 这是写死的情况
#最好是个变量
return redirect(login_url)
```
### app 命名空间 在app 下面的 urls.py中 命名
```
多个app之间 可能产生相同的url 为了避免 reverse('url名字')产生混乱 可以使用命名空间来区分 定义命名空间只需要在 app 下 urls.py 下面 app_name = '新名字'
revser() 就变成了 reverse('新名字:url名字');
示例代码: cms 下 url
app_name = 'cms'
urlpatterns = [
path('',views.index,name='index'),
path('signup/',views.login,name='login') name这里是给url起名字
]
```
### 实例命名空间 在主目录下面的urls.py下 命名
```
一个app 可以拥有多个实例 多个url 可以映射同一个 app 好比 公司有一套后台管理系统 a组 只能通过http://127.0.0.1:9000/cms1 b组只能通过 http://127.0.0.1:9000/cms2
主目录的 urls.py
from django.urls import path,include
urlpatterns = [
path('',include('front.urls')),
path('cms1/',include('cms.urls',namespace='cms1')),
path('cms2/',include('cms.urls',namespace='cms2')), #多个url 指向一个 app
]
views.py
#当你用cms1访问的时候 用cms1的命名空间
#cms2访问 用cms2的命名空间
#获取当前的命名空间
current_namespace = request.resolver_match.namespace
print(current_namespace)
urls = reverse("%s:login" % current_namespace)
return redirect(urls)
cms中views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect,reverse
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse("后台主页")
else:
# return redirect('/login/')
current_namespace = request.resolver_match.namespace
print(current_namespace)
#login_url = reverse('cms:login')
return redirect(reverse("%s:login"%current_namespace))
def login(request):
return HttpResponse("后台登录界面")
# Create your views here.
```
### include函数
```
include(moudule,namespace=None)
* moudule 子url的模块 比如 cms.urls
* namespace 给每个实例起个名字
如果说 你在主目录下面的path 里边写了namespace 实例命名空间 但是 没有写 应用命名空间 app_name
会报错
两种写法
在应用命名空间app_name设置的情况下 一些两种均可使用
path('book/',include('book.urls',namespace='book')),
path('book/',include('book.urls','book')),
```
### re_path
> re_path 跟 path 作用一样 不同的是 re_path 写url的时候 可以使用正则表达式 功能更强大
>
> 写正则表达式的时候 推荐使用原声字符串
> 如果re_path 正则表达式定义变量 用 ()包裹起来 看成一个分组
>
> 参数有名字 前面需要加 ?P ?P<参数名字 >后面跟正则表达式规则
>
>
```
urlpatterns = [
#r'' 表示原生字符串 python正则表达式中 加上r
re_path(r'^$',views.article),
#http://127.0.0.1/article/list/year
#在python中参数有名字 那么需要使用?P<参数名字>
re_path(r'^list/(?P
re_path(r'^list/(?P
]
```
**如果不是特殊要求 (不得不使用正则表达式来解决 ) 能用path 就是用path re_path 容易把代码弄复杂 **
### reverse 补充
```
如果在reverse url的时候 需要添加参数(鼠标放到reverse上 CTRL+点击) 可以添加 kwargs 参数 到reverse 中 示例代码
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse("首页")
else:
#login_url = reverse('login')
#打开首页 自动跳转到 http://127.0.0.1/detail/10/20
#detail_url = reverse('detail',kwargs={"book_id":10,"page":20})
#想要打开首页自动跳转到 http://127.0.0.1/login/?next=
#return redirect(detail_url)
#login_url = reverse('login',kwargs={"?next=":"haha"})#会报错 不支持这种写法
login_url = reverse('login')+"?next=/"#支持这种方法
return redirect(login_url)
def login(request):
return HttpResponse("登录页")
# Create your views here.
def book_detail(request,book_id,page):
text = "您的图书id是:%s" % book_id
return HttpResponse(text)
如果需要添加 查询字符串的参数 比如 打开首页 http://127.0.0.1:9000 自动跳转到 http://127.0.0.1:9000/?next=/
这个时候 kwargs 参数不生效 只能
login_url = reverse('login')+"?next=/" 这种形式
--------------------------------------------------------
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect,reverse
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse('首页')
else:
# login_url = reverse('login')
#打开首页自动跳转http://127.0.0.1:8000/detail/12/12/
# detail_url = reverse('detail',kwargs={"book_id":12,"page":12})
# return redirect(detail_url)
#想要打开首页自动跳转http://127.0.0.1:8000/login/?next=
#+号拼接字符串
login_url = reverse('login')+"?next=/"
return redirect(login_url)
def login(request):
return HttpResponse("登录界面")
def book_detail(request,book_id,page):
text = "您的图书id为:%s" % book_id
return HttpResponse(text)
# Create your views here.
---------------------------------------------
项目url.py
from django.urls import path
from book import views
urlpatterns = [
path('',views.index,name='index'),
path('login/',views.login,name='login'),
path('detail/
]
```
## url 默认参数
```
打开糗事百科 默认查看第一页内容 用户可以选择其它页面
在使用 path 或者 re_path的时候 通过传递参数 打开首页 http://127.0.0.1:9000 显示默认内容
from django.urls import path
from . import views
urlpatterns = [
#path('admin/', admin.site.urls),
path('',views.benshan),
path('page/
]
from django.http import HttpResponse
dongbeiF4 = [
'尼古拉斯赵四',
'刘能',
'宋小宝',
'小沈阳'
]
# def index(request):
# return HttpResponse(dongbeiF4[0])
def benshan(request,page=0):
return HttpResponse(dongbeiF4[page])
```
## 前后端界面
~~~
前端front
views.py:
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect,reverse
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse("前端首页")
else:
# return redirect('/login/')
login_url = reverse('front:login')
print(login_url)
return redirect(login_url)
def login(request):
return HttpResponse('前端登录界面')
# Create your views here.
--------------------------------------------------
urls.py
from django.urls import path
from . import views
app_name='front'
urlpatterns = [
path('',views.index,name='index'),
path('signup/',views.login,name='login')
]
----------------------------------------------------
后端cms
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect,reverse
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse("后端首页")
else:
# return redirect('/login/')
login_url = reverse('cms:login')
print(login_url)
return redirect(login_url)
def login(request):
return HttpResponse('后端登录界面')
# Create your views here.
----------------------------------------------------
urls.py
from django.urls import path
from . import views
app_name = 'cms'
urlpatterns = [
path('',views.index,name='index'),
path('signin/',views.login,name='login')
]
-----------------------------------------------------
项目的urls.py
urlpatterns = [
path('',include('front.urls')),
path('cms/',include('cms.urls')),
]
~~~