Django一(安装&入门)

来源:互联网 发布:网络推广信息方案 编辑:程序博客网 时间:2024/05/16 07:18

本章内容:

  • 安装Django
  • 创建项目与应用
  • 运行项目
  • Django视图
  • https://docs.djangoproject.com/en/1.11/          Django文档

一、安装django

1.1)安装指定版本django

前体条件:已安装好python3且配置好环境变量

cmd.exe

>>> pip3 install django==1.10.3         指定版本pip3安装django

1.2)查看已安装django版本

cmd.ext

>>>pip3 show django

1.3)卸载django

>>>pip3 uninstall django

二、创建项目与应用

查看Django提供的命令

cmd.exe

输入:django-admin   查看Django提供是命令

C:\Users\Administrator>django-admin
 
Type 'django-admin help <subcommand>' for help on a specific subcommand.
 
Available subcommands:
 
[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    runserver--->运行项目
    sendtestemail
    shell
    showmigrations
    sqlflush
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp ------>创建app应用
    startproject---->创建项目
    test
    testserver
Note that only Django core commands are listed as settings are not properly conf
igured (error: Requested setting INSTALLED_APPS, but settings are not configured
. You must either define the environment variable DJANGO_SETTINGS_MODULE or call
 settings.configure() before accessing settings.).
 
C:\Users\Administrator>

a、创建项目

进入到需要创建的目录(自定义)例如:D盘\pydj目录中创建\guest

 cmd.exe

D:\pydj\django-admin startproject guest     #创建guest项目

b、创建app应用

进入新创建项目guest目录

cmd.exe

D:\pydj\guest\python manage.py startapp sign  #创建sign应用

创建成功后目录结构

项目guest中各个目录作用:

  guest/__init__.py   : 一个空的文件,用它标识一个目录为Python的标准包。

  guest/settings.py : Django项目的配置文件,包括Django模块应用配置数据库配置模板配置等

  guest/urls.py        : Django项目的URL声明。

  guest/wsgi.py      : 为WSGI兼容的Web服务器,服务项目的切入点。

  manage.py          : 一个命令工具,可以让你在使用Django项目时以不同的方式进行交互

Django应用【sign】中各个目录作用:

  migrations/: 用于记录models中数据的变更。

  admin.py:映射models中的数据到Django自带的admin后台。

  apps.py  :在新的Django版本中新增,用于应用程序的配置。

  models.py:创建应用程序数据表模型(对应数据库的相关操作)。

      test.py    :创建Django测试。

      views.py  :控制向前端显示那些数据。

三、运行项目

1.1)正常

cmd.exe

D:\pydj\guest\python manage.py runserver

1.2) 端口被占用

Django默认会通过本机的8000端口来启动开发服务器,且仅监听本地连接,如果该端口被占用,需在启动时指定IP地址和端口后

cmd.exe

D:\pydj\guest\python manage.py runserver 127.0.0.1:8001

也可以

D:\pydj\guest\python manage.py runserver 8080

1.3)局域网内其他用户需访问

通过指定一个 IP 地址,你可以告诉服务器–允许非本地连接访问。 如果你想和其他开发人员共享同一开发站点的话,该功能特别有用。 “0.0.0.0”这个 IP 地址,告诉服务器去侦听任意的网络接口。

cmd.exe

D:\pydj\guest\python manage.py runserver 0.0.0.0:8000

完成这些设置后,你本地网络中的其它计算机就可以在浏览器中访问你的 IP 地址了。比如: http://192.168.1.103:8000/

1.4)浏览器访问

打开浏览器访问:http://127.0.0.1:8001  如下图成功:

1.5)Hello Django

第一个例子:Hell Django

在此之前,首先需要配置一下 guest/settings.py文件,将sign应用添加到项目中。

接下来命名一个/index/路径,来显示"Hello Django!"。浏览器地址栏输入:http://127.0.0.1:8001/index/

Django在项目中的guest子目录下通过urls.py文件来定义URLconf。

urls.py

 

接下来../sign/views.py 文件创建index函数

1
2
3
4
5
6
7
8
from django.shortcuts import render
from django.http import HttpResponse
 
# Create your views here.
 
def index(request):
 
   return HttpResponse("Hello Django!")

 定义index函数,并听过HttpResponse类向页面返回字符串"Hello Django!"。

HttpResponse类存在django.http.HttpResponse中,已字符串的形式传递给前端页面数据。

如图已成功:"Hello Django!"

1.6)使用模板

现在使用HTML页面来代替”Hello Django!”字符串,处理方式会有所不同,可以认为是一次重构。

在应用sign/目录下创建templates/index.html文件。

index.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django Page</title>
</head>
<body>
    <h1>Hello Django</h1>
</body>
</html>

 修改视图文件 views.py

1
2
3
4
5
6
7
8
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import  render
 
# Create your views here.
 
def index(request):
   return render(request,"index.html")

 用render函数代替HttpResponse类。render函数的第一个参数是请求对象,第二个参数返回一个index.html页面

1.7)Django工作流

 

PS:   index.html是在templates目录下面。

        这个处理流程并非Django的完整处理过程,其中最主要的就是缺少了数据层(model)的操作。

 1.8) URL组成

作为一个网站的用户,我们会在浏览器的URL地址栏输入:http://127.0.0.1:8001/index/

URL地址由以下几部分组成:

协议类型:HTTP/HTTPS

HTTP协议: 超文本传输协议,用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中哪一个部分,以及那部分内容优先显示。

HTTPS     :  是以安全为目标的HTTP通道,简单讲是HTTP的安全版。

主机地址:baidu.com ,127.0.01

baidu.com为一个网址,网址通过域名解析服务器会找到对应的IP主机。

127.0.0.1为一个IP地址,不过,该IP地址比较特殊,用来指向本机。

端口号:8001

一台主机上有很多应用,不同的应用占用不同的端口号,除了要指定主机(网址或IP地址)之外,还要进一步指定相应的端口号才能访问到具体的应用。

路径:/index/ 、/admin

一般用来表示主机上的一个目录或文件地址

 1.9)urls的配置

当Django拿到浏览器URL的地址之后,取端口号后面的路径 "/index"、”/admin" --->然后在urls.py中匹配。

这里使用Python的正则表达式

通过^index/$ 匹配到/index/目录。并且将处理指向sign应用的视图文件views,py的index函数。

 1.10)views视图

接下来请求的处理到.../sign/views.py 中的index视图函数:

视图在Django中非常重要,是连接页面与数据的中间枢纽。

例如:登录用户在页面上输入了用户名和密码点击登录--->request请求会由视图来接收,

如何提取用户名和密码的数据,如何用这些数据去查询数据库,再如何将登录成功的页面返回给用户,这些全部由视图层来完成

 1.11) templates模板

.../sign/templates/index.html文件

模板就是Web页面,Django自带有模板语言。主要作用是如何展示数据,例如视图层返回的是一个字符串,要如何显示在页面上;返回的对象数组要如何显示等。当然,为了使页面更漂亮需要借助前端技术,CSS、JavaScript等。

 1.12) MTV开发模式

  MTV开发模式:Django的设计鼓励松耦合及对应程序中不同部分的严格分割,遵循这个理念的话,要想修改应用的某部分而不影响其它部分就比较容易了。在视图函数中,我们已经讨论了通过模板系统把业务逻辑和表现逻辑分割开的重要性。在数据库层中,我们对数据访问逻辑也应用了同样的理念。把数据存取逻辑,业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的Model-View-Controller(MVC)模式。在这个模式中,Model代表数据存取层,View代表的是系统中选择显示什么和怎么显示的部分,Controller指的是系统中根据用户输入并需要访问模型,以决定使用哪个视图的那个部分。

M:数据存取部分,由Django数据库层处理;

V:选择显示哪些数据要显示以及怎么显示的部分,由视图和模板处理;

C:根据用户输入委派视图的部分,由Django框架根据URLconfa设置,对给定URL调用适当的Python函数;

由于C由框架自行处理,而Django里更关注的是模型(Model)/模板(Template)和视图(Views),Django也被称为MTV框架。在MTV开发模式中:

M 代表模型(Model)      即数据存取层,该层处理与数据相关的所有事务:如何存取,如何验证;

T 代表模板(Template)  即表现层。该层处理与表现相关的内容:如何在页面或其它类型文档中进行显示;

V 代表视图(View)       即业务逻辑层,该层包含存取模型及调取恰当模板的相关逻辑,可以把它看成模型与模板之间的桥梁。

四、Django视图

 需求:使用Django开发一个简单的发布会签到系统;

1)写个登录

修改../sign/templates/index.html

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>发布会管理</title>
</head>
<body>
    <h1>发布会管理</h1>
    <form>
        <input name="username" type="text" placeholder="username"><br>
        <input name="password" type="password" placeholder="password"><br>
        <button id="btn" type="submit">登录</button>
 
    </form>
</body>
</html>

 访问:http://127.0.0.1:8001/index/

页面上已经看到一个登录功能,但是目前还并不可用;

2)、GET与POST请求

当客户机通过HTTP协议向服务器提交请求时,最常用的方法是GET和POST。

GET   ---从指定的资源请求数据。

POST ---向指定的资源提交要被处理的数据

GET请求

先来看看GET方法如何传参数,给form添加属性method="get"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>发布会管理</title>
</head>
<body>
    <h1>发布会管理</h1>
    <form method="get">
        <input name="username" type="text" placeholder="username"><br>
        <input name="password" type="password" placeholder="password"><br>
        <button id="btn" type="submit">登录</button>
 
    </form>
</body>
</html>

 输入用户名和密码,点击登录。

查看浏览器URL地址栏:http://127.0.0.1:8001/index/?username=admin&password=123456

GET方法会将用户提交的数据添加到URL地址中,路径后面跟问号"?",username和password为HTML代码中<input>标签的name属性值,username=admin表示用户输入框得到的输入数据为admin。password=admin123密码输入框得到的输入数据为[admin123]。多个参数之间用&符号隔开。

 POST请求

将form表单中的属性修改为method="post",这时页面出现【CSRF token missing or incorrect】”跨站请求伪造“。

CSRF跨站请求伪造漏洞,Django针对CSRF的保护措施是在生成的每个表单中放置一个自动生成的令牌,通过这个令牌判断POST请求是否来自同一个网站。

之前的模板都是纯粹的HTML,在这里要使用到Django的模板,使用”模板标签“(template tag)添加CSRF令牌,在from表单中添加{% csrf_token %}。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>发布会管理</title>
</head>
<body>
    <h1>发布会管理</h1>
    <form method="post">
        <input name="username" type="text" placeholder="username"><br>
        <input name="password" type="password" placeholder="password"><br>
        <button id="btn" type="submit">登录</button>
        {% csrf_token %}
 
    </form>
</body>
</html>

 刷新页面并重新提交登录表单,错误提示页面消失

       借助Firebug前端调试工具进行查看POST请求,除了usrname和password参数外,还多了一个csrfmiddlewaretoken的参数。当页面向Django服务器发送一个POST请求时,服务器端要求客户端加上csrfmiddlewaretoken字段,该字段的值为当前会话ID加上一个密匙的散列值。

 如果不需要该检查,可以在../guest/settings.py文件中注释掉csrf

3)、处理登录请求

表单中通过【GET/POST】方法将数据提交给服务器,那么登录数据提交给Django服务器后怎么处理?可以通过form表单的action属性来指定提交路径。

index.html

1
2
3
.....
<form method="post" action="/login_action/">
....

 打开../guest/urls.py 文件添加login_action路径

1
2
3
4
5
6
7
8
9
10
from django.conf.urls import url
from django.contrib import admin
from sign import views   #导入sign应用views文件
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/$',views.index), #添加index/路径
    url(r'^login_action/$',views.login_action),
    url(r'^event_manage/$',views.event_manage)
]

 打开sign/views.py文件,创建login_action视图函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from django.shortcuts import  render
from django.http import HttpResponse
from django.http import HttpResponse,HttpResponseRedirect
 
#登录动作
def login_action(request):
    if request.method == 'POST':
        username = request.POST.get('username','')
        password = request.POST.get('password','')
        if username == 'admin' and password == '123456':
              return HttpResponse('login success!'#登录成功后返回login success!字符串
               
        else:
               return render(request,'index.html',{'error':'username or password error!'})
 
 
def index(request):
       return render(request,"index.html")

      通过login_action函数来处理登录请求,客户端发送的请求信息全部包含在request中。

  首先,通过request.method方法得到客户端发送的请求方式,判断是否为POST请求类型--->通过request.POST来获取POST请求,通过.get()方法寻找name为"username" 和 ”password“的POST参数,如果参数没有提交,返回一个空的字符串。此处的”username" 和“password"对应form表单中<input>标签的name属性,可见这个属性的重要性。

  通过if判断POST请求得到的username 和 password是否为”admin/123456",如果是则通过HttpResponse类返回【login success!】字符串。否则通过render返回index.html登录页面,并且顺带返回错误提示dict{'error':'username or password error!'},需要在index.html页面上添加Django模板:

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>发布会管理</title>
</head>
<body>
    <h1>发布会管理</h1>
    <form method="post" action="/login_action/">
        <input name="username" type="text" placeholder="username"><br>
        <input name="password" type="password" placeholder="password"><br>
        {{error}}<br>
        <button id="btn" type="submit">登录</button>
        {%csrf_token%}
    </form>
</body>
</html>

 登录成功后重定向

  登录成功后返回“login success!”字符串只是一种临时方案,只是为了方便验证登录的处理逻辑,在没有问题之后,需要通过HTML页面来代替

event_manage.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event Manage Page</title>
</head>
<body>
    <h1>Login Success!</h1>
</body>
</html>

 views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.shortcuts import  render
from django.http import HttpResponse
from django.http import HttpResponse,HttpResponseRedirect
 
#登录动作
def login_action(request):
 
    if request.method == 'POST':
        username = request.POST.get('username','')
        password = request.POST.get('password','')
        if username == 'admin' and password == '123456':
            # return HttpResponse('login success!') #登录成功后返回login success!字符串
               return HttpResponseRedirect('/event_manage/'#重定向,将登录成功之后的请求指向/event_manage/目录
        else:
               return render(request,'index.html',{'error':'username or password error!'})
 
#重定向
def event_manage(request):
       return render(request,"event_manage.html")
 
def index(request):
       return render(request,"index.html")

urls.py

1
2
3
4
5
6
7
8
9
10
11
from django.conf.urls import url
from django.contrib import admin
from sign import views   #导入sign应用views文件
 
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/$',views.index), #添加index/路径
    url(r'^login_action/$',views.login_action),
    url(r'^event_manage/$',views.event_manage) #重定向
]

 PS:HttpResponseRedirect类对路径进行重定向,从而将登录成功后的请求指向/event_manage/目录--->创建event_manage函数,用于返回发布会管理event_manage.html页面。需在urls/py 文件中添加路径event_manage/路由。

 4) Cookie 和 Session

Cookie与Session

Cookie机制:正统的Cookie是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示,提示浏览器按照指示生成相应的Cookie。然而客户端脚本JavaScript或者VBScript也可以生成Cookie。而Cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器,浏览器检查所有存储的Cookie,如果某个Cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。

Session机制:Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是散列表)来保存信息。

 4.1 Cookie的使用

views.py文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from django.shortcuts import  render
from django.http import HttpResponse
from django.http import HttpResponse,HttpResponseRedirect
 
#登录动作
 
def login_action(request):
    if request.method == 'POST':
        username = request.POST.get('username','')
        password = request.POST.get('password','')
        if username == 'admin' and password == '123456':
            # return HttpResponse('login success!')                             #登录成功后返回login success!字符串
            response=HttpResponseRedirect('/event_manage/')       #重定向,将登录成功之后的请求指向/event_manage/目录
            response.set_cookie('user',username,3600)                       #添加浏览器cookie
            return response
        else:
            return render(request,'index.html',{'error':'username or password error!'})
 
 
#重定向发布会管理
def event_manage(request):
    username = request.COOKIES.get('user','')                 #读取浏览器cookie
    return render(request,"event_manage.html",{'user':username})
 
 
def index(request):
    return render(request,"index.html")

 修改event_manage.html页面

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event Manage Page</title>
</head>
<body>
    <h1>Login Success!</h1>
    <div style="float: right">
        <a>嗨!{{user}}欢迎</a><hr/>
    </div>
</body>
</html>

 4.2 Session的使用

  Cookie固然好,但存在一定的安全隐患。Cookie像存折,用户的存钱、取钱都会记录在这个存折上(浏览器中会保存所有用户信息),那么对于有非分想法的人可能会去修改存折上的数据(忽略银行同样会记录用户存取款的金额)。

相对于存折,银行卡要安全的多,客户拿到的只是一个银行卡号(浏览器保留一个Sessionid),用户的存款、取钱都会记录在银行的系统里(服务器端),只得到一个Sessinoid是没有任何意义的,所以相对于Cookie来说就安全很多。

在Django中使用Session 和 Cookie类似,将写Cookie的几步操作替换成session即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from django.shortcuts import  render
from django.http import HttpResponse
from django.http import HttpResponse,HttpResponseRedirect
 
#登录动作
 
def login_action(request):
    if request.method == 'POST':
        username = request.POST.get('username','')
        password = request.POST.get('password','')
        if username == 'admin' and password == '123456':
            response=HttpResponseRedirect('/event_manage/'#重定向,将登录成功之后的请求指向/event_manage/目录
            request.session['user'= username #将session信息记录到浏览器
            return response
        else:
            return render(request,'index.html',{'error':'username or password error!'})
 
#重定向发布会管理
def event_manage(request):
    username   = request.session.get('user','') #读取浏览器session
    return render(request,"event_manage.html",{'user':username})
 
 
def index(request):
    return render(request,"index.html")

 再次刷新登录,得到一个错误:no such table: django_session,这个错误和Session的机制有关,既然服务器端要记录用户的数据,那么一定要有地方来存放用户Sessionid对应的信息,所以需要创建django_session表。

cmd.exe

D:\Py_django\guest>python manage.py migrate

PS : Django已经帮我们准备好这些常用的表,只需要将他们生成即可;

       通过migrate命令进行数据库迁移;

      Django默认帮设置sqlite3数据库;

guest项目的根目录下会生成一个db.sqlite3文件。现在验证Session功能是否生效,重新登录成功。

 5、Django认证系统

5.1)、登录Admin后台

    执行manage.py的“migrate"命令时,Django同时也帮我们生产了auth_user表。我们通过URL地址:http://127.0.0.1:8001/admin访问Django自带的Admin管理后台;

在此,之前先来创建登录Admin后台的管理账号:

 

使用创建的超级管理员账号登录:http://127.0.0.1:8001/admin/

5.2)、引用Django认证登录

Django已经帮我们做好了用户体系,可以直接拿来使用。

views.py 文件修改login_action函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from django.shortcuts import  render
from django.http import HttpResponse
from django.http import HttpResponse,HttpResponseRedirect
from django.contrib import auth
 
#登录动作
 
def login_action(request):
    if request.method == 'POST':
        username = request.POST.get('username','')
        password = request.POST.get('password','')
        user     = auth.authenticate(username=username,password=password) #authenticate()认证函数
 
        if user is not None:
            auth.login(request,user) #调用login()方法进行登录
            request.session['user'= username #将session信息记录到浏览器
            response=HttpResponseRedirect('/event_manage/'#重定向,将登录成功之后的请求指向/event_manage/目录
            return response
        else:
            return render(request,'index.html',{'error':'username or password error!'})
 
    else:
        return render(request,"index.html")
#重定向发布会管理
def event_manage(request):
    username   = request.session.get('user','') #读取浏览器session
    return render(request,"event_manage.html",{'user':username})

 authenticate()函数认证给出的用户名和密码,接受两个参数,用户名username和密码password并在用户名和密码正确的情况下返回一个user对象。如果用户名或密码不正确,则authenticate()返回None。

通过if语句判断 authenticate()返回如果不为None,说明用户认证通过。接下来调用login()函数进行登录。login()函数接收HttpRequest对象和一个user对象。

 5.3)、关上其它入口

现在不需要登录就可以直接访问到登录成功页面直接访问:http://127.0.0.1:8001/event_manage/;

所以需要关上该入口,只能通过登录来访问,只需要在这个函数的前面加上@login_required装饰器即可

1
2
3
4
5
6
7
from django.contrib.auth.decorators import  login_required
......
#重定向发布会管理
@login_required()
def event_manage(request):
    username   = request.session.get('user','') #读取浏览器session
    return render(request,"event_manage.html",{'user':username})

 清除浏览器缓存,再次直接访问:http://127.0.0.1:8001/event_manage/  报错提示404

为什么会出现404?

当event_manage()函数被@login_required()装饰器装饰后,默认会跳转到URL中会包含/accounts/login/所以出现404,这种场景下我们需设定跳转到登录页面;

urls.py

1
2
3
4
5
6
7
8
9
10
11
12
from django.conf.urls import url
from django.contrib import admin
from sign import views   #导入sign应用views文件
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/$',views.index)    , #添加index/路径
    url(r'^login_action/$',views.login_action),
    url(r'^event_manage/$',views.event_manage),
    url(r'^$',views.index),
    url(r'^accounts/login$',views.index),
]

 当访问以下链接,都会跳转到登录页面

http://127.0.0.1:8001/

http://127.0.0.1:8001/index/

http://127.0.0.1:8001/event_manage/

http://127.0.0.1:8001/login_action/

原创粉丝点击