django -- url映射

* 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//',views.book_detail),
    path('book/author/',views.author_detail),#author没有参数
    path('book/detail//',views.book_detail)#使用<> 传递参数  记住  <里边的变量> 要跟应用views下面的 参数一样  跟上面的 book_id 一样
]
```

### 指定参数的类型  

```
def publisher_detail(request,publisher_id):
    text = '出版社的id是:%s' % publisher_id
    return HttpResponse(text)
from django.urls import converters (鼠标放上去 ctrl+点击)    
path('book/publisher/',views.publisher_detail)
path('book/publisher/',views.publisher_detail)
path('book/publisher/',views.publisher_detail)
path('book/publisher/',views.publisher_detail)
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//',views.book_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/(?P2\d{3})/$',views.article_list),
    re_path(r'^list/(?P\d{2})/$',views.article_list_month),
]
```

**如果不是特殊要求 (不得不使用正则表达式来解决 ) 能用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///',views.book_detail,name='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//',views.benshan)
]


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')),
      ]

~~~

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