Django进阶(一)

Url进阶

mysit/mysit/urls.py

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

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
]

# urlpatterns=[
#     url(正则表达式,视图函数,参数,别名)
# ]
#
# 正则表达式:python正则表达式的所有规则都适应,当用户输入满足正则表达式的地址时就会执行对应的视图函数
# 视图函数:urls本质是一个映射表,每个url地址都对应一个视图函数,第一个参数是地址,第二个参数就是处理这个地址的视图函数
# 参数:视图函数有时需要参数,就需要第三个参数来给视图函数传递参数,是字典形式的参数
# 别名:这个是用在前端的,一会儿会介绍
#
# 当我们每次新建一个URL和其对应的视图函数时都会在views.py中的urlpatterns列表里添加“url(正则表达式,视图函数,参数,别名)”

小实例1

mysit/mysit/urls.py修改如下

from django.conf.urls import url
from django.contrib import admin
from blog import views# 导入blog下的views.py

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^years/[0-9]{4}‘,views.years)
    # 满足正则表达式则‘^years/[0-9]{4}‘ 则运行views.years视图函数
]

mysit/blog/views.py修改如下

from django.shortcuts import render, HttpResponse

# Create your views here.

def years(requst):
    return HttpResponse("this is my webpage")

运行,输入网址显示效果:


小实例2

继续修改

mysit/blog/views.py修改如下

from django.shortcuts import render, HttpResponse

# Create your views here.

def years(requst, var_one,var_year):
    # 这次我们视图函数需要一个参数var_year,并将该参数返回给页面
    return HttpResponse(str(var_one)+str(var_year))

mysit/mysit/urls.py修改如下

from django.conf.urls import url
from django.contrib import admin
from blog import views

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),

    url(r‘^years/[0-9]{4}‘, views.years, {"var_year": 2008, "var_one": "years"})
    # 满足正则表达式则‘^years/[0-9]{4}‘ 则运行views.years视图函数,
    # 由于视图函数views.years需要参数,所以我们的url()也要添加第三个参数
    # 第三个参数将视图函数所需的参数封装成字典,key为views.years中的参数名称,value是想要给他的值

    # 另一种传递参数方法
    # url(r‘^(years)/([0-9]{4})‘,views.years)
    # 正则表达式中只要用()包含起来的内容都会当作参数传递给views.years
    # 只能按照括号的顺序挨个给视图函数中的参数

    # 另一种传递参数方法    # url(r‘^(?P<var_one>years)/(?P<var_year>[0-9]{4})‘,views.years)    # 正则表达式中用()包含起来的内容有了名字  ?P<name>  传递给视图函数的时候会找到相对应的参数    # 可以不按照顺序
 ]

运行,输入网址显示效果:


小实例3

mysit/templates下新建myhtml.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#form表单提交的数据内容都会交给action中的index (127.0.0.1:8000/index,省略了IP和端口)去处理#}
<form action="/index/" method="post" >
    <input type="text">
    <input type="submit" value="提交">
</form>

</body>
</html>

mysit/mysit/urls.py修改如下

from django.conf.urls import url
from django.contrib import admin
from blog import views

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^index‘, views.years)
]

mysit/blog/views.py修改如下

from django.shortcuts import render, HttpResponse

# Create your views here.

def years(requst):
    if requst.method == "POST":
        # 提交表单的时候是POST请求,返回提交成功
        return HttpResponse("提交成功!")

    # 第一次访问为GET请求  直接返回带有表单的页面
    return render(requst, "myhtml.html")


运行,结果正常,可是如果有个需求,需要你改变一下网址,不是输入http://127.0.0.1:8000/index/会访问该页面,而是输入http://127.0.0.1:8000/index/pay访问该页面,那么你需要修改两个地方:

1. 将mysit/mysit/urls.py 中的“url(r‘^index‘, views.years)”修改为“url(r‘^index/pay‘, views.years)”,

2,将mysit/templates/myhtml.html中的“<form action="/index/" method="post" >”修改为“<form action="/index/pay/" method="post" >”,

可能并不感觉麻烦,但是我的需求不想让前端修改HTML代码,怎么办?这就引入了 url(正则表达式,视图函数,参数,别名)中的“别名”

小实例4

mysit/blog/views.py不用修改

mysit/templates/myhtml.html修改如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#form表单提交的数据内容都会交给urls.py中别名为“pay”对应的视图函数去处理#}
{#固定写法action={% url " " %} 引号中为别名,与后端urls.py中的别名一致#}
<form action={% url "pay" %} method="post" >
    <input type="text">
    <input type="submit" value="提交">
</form>

</body>
</html>

mysit/mysit/urls.py修改如下

from django.conf.urls import url
from django.contrib import admin
from blog import views

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^index/$‘, views.years, name="pay")
    # 固定写法 name="" 引号中为别名
    # 别名的作用就是当需要修改正则表达式,即当你需要换网址的时候不用修改前端的HTML页面
    # 前提是你的name值与前端的{% url " " %}引号中的值一样
]

这样,无论你想修改什么样的正则表达式,即想修改什么样的网址,前端都不用动,提交表单时,都会去找别名为“pay”所对应的视图函数。


小实例5

肯定有人问,如果一个网站有成千上万个url地址,那么都放到mysit/mysit/urls.py里吗?既不容易修改,也不利于查找,怎么办?

mysit/mysit/urls.py修改如下

from django.conf.urls import url,include
# 导入include模块
from django.contrib import admin

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^blog/‘,include("blog.urls"))
    # 固定语法 以后所有以blog开头的地址,都会去blog/urls.py中去查找分发
    # url(正则表达式,include("对应的app urls"))
]

mysit/blog/下新建urls.py

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

urlpatterns = [
    url(r‘index/‘, views.years, name="pay"),
    url(r‘index2/‘, views.years, name="pay2"),
    url(r‘index3/‘, views.years, name="pay3")

]

这样问题就解决了,mysit/mysit/urls.py其实是总的URL分发,满足条件则去 mysit/blog/urls.py实现具体分发

View进阶

可能你会有疑惑,为什么每次在views.py中写视图函数的时候,每个函数必须有个参数request,现在我们来一探究竟:

HttpRequest对象

from django.shortcuts import render

# Create your views here.

def years(request):
    # request其实是一个HttpRequest对象,他包含了用户传递过来的所有信息,主要属性及方法如下:

    print("request.path:" + str(request.path))
    # 执行结果:request.path:/blog/index/
    # 请求页面的全路径,不包括域名

    print("request.method:" + str(request.method))
    # 执行结果:request.method:GET
    # 请求中使用的HTTP方法的字符串表示。全大写表示
    # GET:         包含所有HTTP GET参数的类字典对象
    #
    # POST:       包含所有HTTP POST参数的类字典对象
    #
    #              服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
    #              HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
    #              if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"

    print("request.COOKIES:" + str(request.COOKIES))
    # 执行结果:request.COOKIES:{}
    # 包含所有cookies的标准Python字典对象;keys和values都是字符串。

    print("request.session:" + str(request.session))
    # 执行结果:request.session:<django.contrib.sessions.backends.db.SessionStore object at 0x7fa23a3e37f0>
    # session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。

    print("request.user:" + str(request.user))
    # 执行结果: request.user:AnonymousUser
    # user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
    #              没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
    #              可以通过user的is_authenticated()方法来辨别用户是否登陆:
    #              if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
    #              时该属性才可用

    print("request.FILES:" + str(request.FILES))
    # 执行结果:request.FILES:<MultiValueDict: {}>
    # FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中
    #       name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
    #
    #             filename:      上传文件名,用字符串表示
    #             content_type:   上传文件的Content Type
    #             content:       上传文件的原始内容
    # 方法
    # get_full_path(), 比如:http://127.0.0.1:8000/index33/?name=123,
    # req.get_full_path()
    # 得到的结果就是 /index33/?name =123 包括用户GET过来的数据
    # 而req.path: 则得到 /index33 不包括用户GET过来的数据
    return render(request, "myhtml.html")

HttpResponse对象

每个view请求处理方法必须返回一个HttpResponse对象。所以每个views.py下的函数都会return一个HttpResponse对象,其实render、HttpResponse以及还每接触到的redirect都是HttpResponse对象,HttpResponse只是返回一堆HTML字符串他不会渲染网页,假如你的网页中存在变量,则需要render,假如页面跳转,那么就需要redirect,下面实例告诉你redirect和render的区别。

我们实现一个功能:浏览器输入网址http://127.0.0.1:8000/blog/index/将myhtml.html页面返回给用户让用户登录,用户点击提交后将myhtml2.html页面返回给用户,下面我们先用render进行实现:

mysit/templates/新建myhtml.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#form表单提交的数据内容都会交给urls.py中别名为“pay”对应的视图函数去处理#}
<form action={% url "pay" %} method="post" >
    <input type="text">
    <input type="submit" value="提交">
</form>

</body>
</html>

mysit/templates/新建myhtml2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{# 视图函数返回来的username进行显示 #}
欢迎{{ username }}登录
</body>
</html>

mysit/mysit/urls.py进行路径分发,满足条件‘^blog/‘则去 mysit/blog/urls.py实现具体分发

from django.conf.urls import url,include
# 导入include模块
from django.contrib import admin

urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘^blog/‘,include("blog.urls"))
    # 所有以“blog/”开头的url地址都分配给"blog.urls"再进行分发
]

mysit/blog/urls.py

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

urlpatterns = [
    url(r‘index/$‘, views.myhtml, name="pay"),
   # 分别分配视图函数
    url(r‘index2/$‘, views.myhtml2),

]

mysit/blog/views.py

from django.shortcuts import render, HttpResponse, redirect

# 首先导入 HttpResponse, redirect

# Create your views here.

def myhtml(request):
    if request.method == "POST":
        # 做一些判断 判断成功后将 登录后的页面"myhtml2.html" 返回给用户
        return render(request, "myhtml2.html")

    return render(request, "myhtml.html")

def myhtml2(request):
    username = "IDKTP"
    # 一些操作 比如从数据库拿到该用户的某些信息 然后返回页面给用户
    # 我们只返回给用户自己的姓名进行显示 让页面显示 欢迎IDKTP登录
    return render(request, "myhtml2.html", {"username": username})

点击运行,浏览器输入网址http://127.0.0.1:8000/blog/index/,再在页面中点击“提交”按钮,你会发现:

那是因为render直接在当前url网址(127.0.0.1:8000/blog/index)中把myhtml2.html页面返回给了用户,而在def myhtml2(request)视图函数中的所有操作(给username进行赋值)都没有进行,所以myhtml2.html中的“{{ username }}”为空,所以没有显示。

而redirect则会直接改变地址栏中url地址,然后根据url分发找到def myhtml2(request)视图函数,然后在返回myhtml2.html页面

mysit/blog/views.py修改如下

from django.shortcuts import render, HttpResponse, redirect

# 首先导入 HttpResponse, redirect

# Create your views here.

def myhtml(request):
    if request.method == "POST":
        # 做一些判断 判断成功后将 登录后的页面"myhtml2.html" 返回给用户
        return redirect("/blog/index2")
        # redirect("")引号内为页面myhtml2.html对应的url地址

        # "/blog/index2"开头以“/”开头 证明url地址是"/blog/index2"直接和 域名 进行拼接
        # (127.0.0.1:8000/blog/index2)

        # "blog/index2"不是以“/”开头 证明url地址是 你跳转之前的url地址 和 "blog/index2"进行拼接
        # (127.0.0.1:8000/blog/index/blog/index2)

    return render(request, "myhtml.html")

def myhtml2(request):
    username = "IDKTP"
    # 一些操作 比如从数据库拿到该用户的某些信息 然后返回页面给用户
    # 我们只返回给用户自己的姓名
    return render(request, "myhtml2.html", {"username": username})

这样就实现了我们想要的结果了!

时间: 2023-12-26 05:04:43

Django进阶(一)的相关文章

python 全栈 web框架 Django进阶

django 进阶 基础中,一些操作都是手动创建连接的非主流操作,这样显得太low,当然也是为了熟悉这个框架! 实际中,django自带连接数据库和创建app的机制,同时还有更完善的路由系统机制.既然基础已经了解,那就聊聊主流的东西. 一.web框架重新认知: 既然都是框架,那肯定是都包含了这些模块和对应的功能!但是不同框架之间也是有些诧异,毕竟封装的方法不同. Django: - 路由(url路由系统) - 视图(视图函数) - 模板(模版页面) - 数据库 ---> ORM(类-表:对象-行

Python之路,Day16 - Django 进阶

Python之路,Day16 - Django 进阶 本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproject.com/en/1.9/topics/pagination/ 自定义template tags https://docs.djangoproject.com/es/1.9/howto/custom-template-tags/ 权限管理 django 自带有基本的权限管理 ,但粒度和限制权限的维度

【Python之路Day18】Python Web框架之 Django 进阶操作

Django 进阶篇 一.django的Model基本操作和增.删.改.查. 注:默认使用了sqlite3数据库 如果想使用其他数据库,请在settings里修改 1.创建数据库: 1.创建model类 在app01(或者你的app下)下models.py写入以下内容: from django.db import models # Create your models here. # 这个类是用来生成数据库表的,这个类必须集成models.Model class UserInfo(models.

django进阶-3

先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py 1 from django.db import models 2 from django.utils.html import format_html #把字符串变成html 3 4 # Create your models here. 5 class Author(models.Model): 6 first_name = models.CharFiel

【Python全栈-后端开发】Django进阶2-Form表单

Django进阶2-Form表单 Django的Form主要具有一下几大功能: 生成HTML标签(可以保留上次输入内容) 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 一.小试牛刀 1.创建Form类 在app01 文件夹下-->创建新的.py 文件 from django.forms import Form from django.forms import widgets from django.forms import fields class M

python Django 进阶篇

Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. 1,基本配置 一.创建django程序 终端命令:django-admin startproject sitename IDE 创建Django程序时,本质上都是自动执行上述命令 其他常用命令: python manage.py runserver 0.0.0.0 python manage.py

Web框架Django进阶

一.Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetList(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost') cursor = db.cursor() curso

Django进阶 (二)

规范 确立规范的好处: 代码可读性高 方便代码的定位极其查找 为以后代码扩容带来便利 场景: 在多个APP的场景下,单个app的URL函数功能较多的时候,我们可以通过以下方法来解决. 把Views写成模块的方式并且为不同的功能进行不同的划分,并且在Templates中使用同样规则,如下图: 我根据不同的html然后创建不同的函数,命名和templates模板目录一样这样非常方便找到,这个页面中的函数在哪里. 设置路由的时候就得导入相应的函数(下面的函数是在app01中的url,通过object的

Django进阶知识

Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 import MySQLdb def GetList(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost') cursor = db.cursor() cursor.