谈谈Python之Django搭建企业级官网(第三篇下部)

转载请注明来源地址和原作者(CFishHome)

前沿

上一篇文章我们学习了URL与视图函数的映射、传递参数的三种方式、转换器的简单使用和include函数分层映射管理。接下来这一篇文章着重介绍Path、re_path、include、reverse、redirect函数的使用和自定义URL转换器。学完这些内容,相信我们对URL和视图都会有了一定的了解和认识。为了让每篇文章具有一定的独立性,我决定每篇文章都重新新建一个项目,便于测试和调试。

预备

首先,我们在Pycharm重新新建一个名为book_project的Django项目,然后打开CMD窗口进入虚拟环境,接着跳转到该项目的目录下(含有manage.py),再依次执行创建app命令,如下图:

创建完成后,该项目的样子大概是酱紫的:

模拟前端和后端

我们想实现:front前端拥有前端首页和前端登陆页面,而cms后端拥有后端首页和后端登陆页面,然后分别输入配置好的URL对这四个页面进行访问。
首先,为cms和front两个app手动添加urls.py文件。然后分别按以下步骤添加或修改项目文件代码:
(1)为cms的urls.py文件添加以下代码:

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index),
    path("login/", views.login)
]

(2)为front的urls.py文件添加以下代码:

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index),
    path("login/", views.login)
]

(3)为cms的views.py文件添加以下代码:

from django.http import HttpResponse

def index(request):
    return HttpResponse("后端首页")

def login(request):
    return HttpResponse("后端登陆页面")

(4)为front的views.py文件添加以下代码:

from django.http import HttpResponse

def index(request):
    return HttpResponse("前端首页")

def login(request):
    return HttpResponse("前端登陆页面")

(5)为book_project这个主包的urls.py文件添加以下代码:

from django.urls import path,include

urlpatterns = [
    path(‘‘, include("front.urls")),
    path(‘cms/‘, include("cms.urls"))
]

如果学习了上一篇文章的内容,我相信这些代码的编写是完全OK的。好,我们运行一下项目(注意,我们是新建的项目,记得在勾选单一实例运行。)。
运行结果如下(完美,成功运行~):

实际需求

模拟自动跳转新用户登陆页面

实际需求:要想实现一个类似于知乎主页一样,若是新用户第一次登陆知乎,不管哪个页面都会跳转到登陆账号的页面,对于这一需求,我们可以通过以下模拟实现(为了更好观察代码,一样的代码部分我直接提示省略):
(1)修改front前台的index视图函数

#省略上面代码
from django.shortcuts import redirect  # 导入重定向redirect函数,最好记住redirect函数源于哪个模块,因为要经常重定向。

def index(request):
    # ?username=xxx
    username = request.GET.get(‘username‘)  # 当用户输入127.0.0.1:8000,检测到没有账户则跳转到注册页面,当输入http://127.0.0.1:8000/?username=1正常显示前台首页。
    if username:
        return HttpResponse(‘前台首页‘)
    else:
        return redirect(‘/login/‘)  # 跳转通过redirect函数来进行页面重定向,重新访问指定的url页面
#省略下面代码

修改完代码后,按下Ctrl+S保存(自动重新编译项目)。注意观察,输入127.0.0.1:8000会发现自动跳转到127.0.0.1:8000/login/。

重定向代码的缺陷

其实还存在这样一种情况,假如老板或项目经理突然脑袋秀逗了,要求你更改网页的URL,将127.0.0.1:8000/login/更改为127.0.0.1:8000/signin/,假如这时还采用上面的代码进行网页重定向,那你会非常抓狂,举我们这个项目栗子来说,不单只要修改为下面这样:

urlpatterns = [
    path("", views.index),
    path("signin/", views.login)
]

还要修改重定向位置的代码这样:

def index(request):
    # ?username=xxx
    username = request.GET.get(‘username‘)  # 当用户输入127.0.0.1:8000,检测到没有账户则跳转到注册页面,否则正常显示前台首页。
    if username:
        return HttpResponse(‘前台首页‘)
    else:
        return redirect(‘/singin/‘)  # 跳转通过redirect函数来进行页面重定向,重新访问指定的url页面

如果公司网站项目十分庞大的话,那可能还有很多地方都要修改,这十分耗时也费力。所以,我们推荐为URL命名来解决这一问题,给URL取个名字,只要调用reverse反转URL的名字而不是直接重定向写死的URL,那么无论URL怎么修改也影响不到其他地方。

Path函数

在学习URL命名之前,先详细学习下Path函数的使用。
path 函数的定义为:

path(route,view,name=None,kwargs=None)  。

以下对这几个参数进行讲解。

  1. route 参数: url 的匹配规则。这个参数中可以指定 url 中需要传递的参数,上一篇文章已讲解,这个参数不再赘述。请移步到谈谈Python之Django搭建企业级官网(第三篇上部)
  2. view 参数:可以为一个视图函数或者是 类视图.as_view() 或者是 django.urls.include() 函数的返回值。
  3. name 参数:这个参数是给这个 url 取个名字的,这在项目比较大, url 比较多的时候用处很大。这个参数就是用于URL命名。
  4. kwargs 参数:有时候想给视图函数传递一些额外的参数,就可以通过 kwargs 参数进行传递。这个参数接收一个字典。会将foo=bar作为关键字实参传入视图函数,所以视图函数要有形参来接收实参。
    比如以下的 url 规则:
    from django.urls import path
    from . import views
    urlpatterns = [
        path(‘blog/<int:year>/‘, views.year_archive, kwargs={‘foo‘:‘bar‘}),
    ]

    那么以后在访问 blog/1991/ 这个url的时候,会将{‘foo‘:‘bar‘}作为关键字参数传给 year_archive函数。year_archive视图函数的形参中最后添加一个kwargs参数来接收这个额外的参数。

URL命名

学习完path函数各参数,相信都知道该函数的name参数就是用于URL命名的了。
接下来修改front包的urls.py文件代码如下:

urlpatterns = [
    path("", views.index),
    path("login/", views.login, name=‘login‘)
]

再次修改front包的views.py文件代码如下:

#省略上面代码
from django.shortcuts import redirect, reverse  # 注意这里添加了reverse函数,reverse函数用于将指定URL名字反转成URL。

def index(request):
    # ?username=xxx
    username = request.GET.get(‘username‘)  # 当用户输入127.0.0.1:8000,检测到没有账户则跳转到注册页面,否则正常显示前台首页。
    if username:
        return HttpResponse(‘前台首页‘)
    else:
        # reverse(‘login‘)函数返回‘/login/’
        return redirect(reverse(‘login‘))  # 跳转通过redirect函数来进行页面重定向,重新访问指定的url页面(相当于重新访问127.0.0.1:8000/login/)
#省略下面代码

按下Ctrl+S保存,输入127.0.0.1:8000成功跳转到127.0.0.1:8000/login登陆页面。

应用命名空间

在公司实际开发中,如果公司里的多个人同时负责网站的开发,而且A同事负责开发front的app,B同事负责开发cms的app,那么由于两个app都有首页和登陆页面,那么有可能url的name属性可能会相同冲突。在多个app之间,有可能产生同名的url,这时候为了避免反转url的时候产生混淆,可以使用应用命名空间来做区分。定义应用命名空间非常简单,只要在“app”的“urls.py”中定义一个叫做“app_name”的变量,来指定这个应用的命名空间即可。
就好比我们的项目,将front包里的urls.py和views.py文件和cms包里的urs.py和views.py文件分别为URL映射命名为index和login,如下图所示:

运行项目,输入127.0.0.1:8000自动跳转到127.0.0.1:8000/cms/login网页,而不是之前的127.0.0.1:8000/login网页,由于多个app的URL拥有相同的名字,所以Django在执行reverse函数反转URL时懵逼了。为了解决这个问题,我们将采用应用命名空间。
修改front包的urls.py文件的代码如下(django在执行到app时,会自动读取这个应用命名空间并将这个名字作为app的名字):

from django.urls import path
from . import views

app_name = "front"  # 添加了应用命名空间

urlpatterns = [
    path("", views.index, name="index"),
    path("login/", views.login, name=‘login‘)
]

以后在做反转的时候就可以使用“应用命名空间:url名称”的方式进行反转。示例代码如下修改front包的views.py文件的代码如下:

def index(request):
    # ?username=xxx
    username = request.GET.get(‘username‘)  # 当用户输入127.0.0.1:8000,检测到没有账户则跳转到注册页面,否则正常显示前台首页。
    if username:
        return HttpResponse(‘前台首页‘)
    else:
        return redirect(reverse(‘front:login‘))  # 这里为URL名字前面添加front应用命名空间名

按下Ctrl+S保存,输入127.0.0.1:8000自动跳转到127.0.0.1:8000/login网页,成功了,Django不会再懵逼了。

include函数

在上一篇文章我们知道,在项目不断庞大以后,经常不会把所有的 url 匹配规则都放在项目的 urls.py 文件中,而是每个 app 都有自己的 urls.py 文件,在这个文件中存储的都是当前这个 app 的所有url 匹配规则。然后再统一include到项目的 urls.py 文件中。 include 函数有多种用法,这里讲下几种常用的用法:
(1)include(pattern,namespace=None) :直接把其他 app 的 urls 包含进来。
之前的include用法,举个栗子(下面的代码仅用于解释用法,不是将代码添加到项目):

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
        path(‘admin/‘, admin.site.urls),
        path(‘book/‘,include("book.urls"))
]

我们可以发现这一种用法其实该函数还有参数2指定实例命名空间,默认是None。但是在使用实例命名空间之前,必须先指定一个应用命名空间,不先指定应用命名空间会报错。一个app可以创建多个实例,也就是可以使用多个url映射同一个app,所以这就产生一个问题。以后在做反转的时候,如果使用应用命名空间,那么就会发生混淆。
将book_project主包的urls.py文件代码修改如下:

from django.urls import path,include

urlpatterns = [
    path(‘‘, include("front.urls")),
    path(‘cms1/‘, include("cms.urls")),  # 这两行代码代表输入127.0.0.1:8000/cms1或127.0.0.1:8000/cms2能映射到cms.urls内部的url路径。
    path(‘cms2/‘, include("cms.urls"))
]

为cms包的urls.py文件添加应用命名空间:

app_name = "cms"

为cms包的views.py文件修改代码如下:

def index(request):
    # ?username=xxx
    username = request.GET.get(‘username‘)  # 当用户输入127.0.0.1:8000,检测到没有账户则跳转到注册页面,否则正常显示前台首页。
    if username:
        return HttpResponse(‘后台首页‘)
    else:
        return redirect(reverse(‘cms:login‘))  # 这里使用了应用命名空间反转URL

经过上面代码的修改,这时候按下Ctrl+S保存,输入127.0.0.1:8000/cms1成功跳转到127.0.0.1:8000/cms1/login,但是当输入127.0.0.1:8000/cms2却自动跳转到了127.0.0.1:8000/cms1/login,what?我的127.0.0.1:8000/cms2/login哪里去了?导致上面的原因就是前面介绍的一个app可以创建多个实例,也就是可以使用多个url映射同一个app,所以这就产生一个问题。以后在做反转的时候,如果使用应用命名空间,那么就会发生混淆。为了避免这个问题,我们可以使用实例命名空间。实例命名空间也是非常简单,只要在“include”函数中传递一个“namespace”变量即可。
在上面代码的基础上继续修改代码,修改cms包的views.py文件代码如下:

def index(request):
    username = request.GET.get(‘username‘)
    if username:
        return HttpResponse("后端首页")
    else:
        current_namespace = request.resolver_match.namespace  # 返回当前app对应的实例命名空间(cms1或cms2)
        return redirect(reverse(‘%s:login‘ % current_namespace))  # 相当于"cms1:login"或”cms2:login“

接着修改book_project主包的urls.py文件代码如下:

from django.urls import path,include

urlpatterns = [
    path(‘‘, include("front.urls")),
    path(‘cms1/‘, include("cms.urls", namespace="cms1")),  # 使用了实例命名空间namespace
    path(‘cms2/‘, include("cms.urls", namespace="cms2"))
]

这时候按下Ctrl+S保存,输入127.0.0.1:8000/cms1成功跳转到127.0.0.1:8000/cms1/login,然后输入127.0.0.1:8000/cms2也成功跳转到了127.0.0.1:8000/cms2/login页面。如下图:

(2)include((pattern_list,app_namespace),namespace=None) :“include”函数的第一个参数既可以作为一个字符串,也可以作为一个元组,如果是元组,那么元组的第一个参数是子“urls.py”模块的字符串,元组的第二个参数是应用命名空间,也就是说应用命名空间既可以在子“urls.py”种通过"app_name"指定,也可以在“include”函数中指定。
将book_project主包的urls.py文件代码修改如下:

from django.urls import path, include
from front import views

urlpatterns = [
    path(‘‘, include(([
                          path(‘‘, views.index, name="index"),
                          path("login/", views.login, name=‘login‘)
                      ], "front"))),  # 注意
    path(‘cms1/‘, include("cms.urls", namespace="cms1")),
    path(‘cms2/‘, include("cms.urls", namespace="cms2"))
]

上面的代码相当于完全忽略了front包的urls.py文件的作用,因为已经被include函数的第一个参数列表给替代了,所以urls.py文件的“app_name = "front"”指定的应用命名空间自然也失效了。这时运行代码完全OK,跟之前的一摸一样,输入127.0.0.1:8000自动跳转到127.0.0.1:8000/login页面。
(3)include(pattern_list) :可以包含一个列表或者一个元组,这个元组或者列表中又包含的是 path 或者是 re_path 函数(该函数后面会讲)。
这个函数跟上一个函数差不多,也是用含有path函数的列表或元组替代了之前的pattern。但是需要注意的是,因为这样会忽略了front包的urls.py文件的作用,所以urls.py文件的“app_name = "front"”指定的应用命名空间自然也失效了。那么如果你映射的视图函数内部进行反转URL时指定了应用命名空间,那么将会报错,会提示找不到front命名空间,如下:

所以,综上建议,如果你映射的视图函数内部进行反转URL时指定了应用命名空间,最好调用include((pattern_list,app_namespace),namespace=None) 函数,在指定列表或元组 的同时也指定应用命名空间。

后面的内容明天补充.....

原文地址:http://blog.51cto.com/12731497/2175667

时间: 2024-07-31 14:46:14

谈谈Python之Django搭建企业级官网(第三篇下部)的相关文章

谈谈Python之Django搭建企业级官网(第三篇上部)

转载请注明来源地址和原作者(CFishHome) 前沿 上一节的学前准备工作和第一个小牛试刀的Django项目学习,让我们对Django开发越来越感兴趣了.正所谓趁热打铁,让我们继续来学习网站开发必备的视图函数和URL映射等知识,跟着步伐一起学习,我相信你会收获很多.噔~噔,新闻播报时间:9月12-9月16有两个超强台风在广东湛江登陆,沿途影响众多城市,包括深圳!!所以很遗憾,前几天打算和舍友去深圳游玩的计划泡汤了,也只能推迟几天前往深圳度中秋.看月亮了~ DEBUG模式 无论是使用命令行还是P

Django打造大型企业官网(三)

四.前端首页 4.1.导航条实现 (1)templates/new/index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>知了课堂</title> <link rel="stylesheet" href="../../dist/css/index.min

Django学习笔记 官网教程纠正 代码

原文: Django学习笔记 官网教程纠正 代码 Django学习笔记 4.模板初学中,照书例django book 出现以下异常 raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE) ImportError: Settings cannot be imported, because environmen

使用 Python 和 Django 搭建 Web 应用

使用 Python 和 Django 搭建 Web 应用 简介 Django 是 Python 开发的 Web 框架.使用 Django 搭建 Web 应用很方便. 写本文时 django 的最新版本为 1.4,但本文不关注新版本的特性,只搭建一个简单的应用. 安装 Django 本文以 CentOS 6.2 为例进行安装: 安装 python # yum install python 本文使用的是 CentOS 6.2 Desktop,默认安装了 python. 查看一下 python 的版本

《健康报》携手健康之路帮助医院医生免费搭建微官网

健康报讯由健康报社与北京健康之路众康信息技术有限公司联合推动的医疗机构微官网及手机APP普及project公益服务项目,5月12日正式启动,将免费为全国各类医疗机构及医务人员搭建微官网和手机client(APP). 随着移动互联网技术的迅猛发展.人们越来越多地通过智能手机获取资讯和服务.医疗机构微官网及手机APP普及project将帮助医疗机构建设微官网.APP等移动互联网工具.帮助医疗卫生机构推动医院信息化建设,优化服务流程,提升服务质量.方便患者就医.该project也对医务人员开放,帮助医

程序员必知的技术官网系列--spring篇

进入官网首先看到的是官网的轮播和首页导航,其中首页导航有四个, 下图有详细介绍, 随后也会单独讲解个导航包含的内容,本文只介绍前两个导航栏的内容, 本文只负责介绍官网的页面结构和文章用到的页面的内容翻译来辅助官网内容结构的讲解, 不做具体技术文档的解释, 以后有机会了再做解释. 好了开干. 首页 官网首页导航 看完导航栏后我们先往下滚动可以看到spring全家桶中的三个明星产品:spring boot,spring cloud,spring data flow和一个居中的标题spring:the

Python爬取王者荣耀官网,实现一对一下载软件!

效果: 我没有弄文件夹保存,因为皮肤与英雄都是一一对应,这样子更加方便操作. 点击下载皮肤后,会自动从官网下载一个json文件,所以出了新英雄.新皮肤软件会自动更新.高清图: 但是有个别新皮肤官网也没有提供数据,找不到新皮肤下载的选择项时,点击影藏皮肤获取按钮输入英雄名字,再点击隐藏皮肤下载即可. 环境: 系统:Windows 模块:requests. json.os.time.tkinter 编辑器:sublime(获取视频教程) tkinter部分代码 界面还算比较简单的,就那么几个组件.

python爬取银行名称和官网地址

爬取所有银行的银行名称和官网地址(如果没有官网就忽略),并写入数据库.目标网址:http://www.cbrc.gov.cn/chinese/jrjg/index.html(因为此网站做了反爬虫机制,所以这里需要我们将爬虫伪装浏览器进行访问.)关于爬虫伪装成浏览器访问可以参考这篇文章:https://blog.csdn.net/a877415861/article/details/79468878 话不多说直接上代码: import re from urllib import request f

Django搭建及源码分析(三)---+uWSGI+nginx

每个框架或者应用都是为了解决某些问题才出现旦生的,没有一个事物是可以解决所有问题的.如果觉得某个框架或者应用使用很不方便,那么很有可能就是你没有将其使用到正确的地方,没有按开发者的设计初衷来使用它,当你将一个框架的优势使用到极致时一定是非常舒服和顺手的一件事.但同时也有可能衍生另一个问题,这个框架只解决了你的问题一,没有解决问题二.三等等,因此,就出现了多个框架/应用相结合的情况.比如Django + uWSGI + nginx. 本人初学python,找了一些实例进行了一些操作,以下纯属目前的