Django基础入门(一)
一、Django介绍
1.1 Django介绍
Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django是一个开放源代码的Web应用框架,由Python写成。Django遵守BSD版权,初次发布于2005年7月, 并于2008年9月发布了第一个正式版本1.0 。Django采用了MVC的软件设计模式,即模型M,视图V和控制器C。
Django官网:https://www.djangoproject.com/
官方文档:https://docs.djangoproject.com/en/2.0/
1.2 Django的安装
官网链接:https://www.djangoproject.com/download/
1.3 创建和启动工程
django-admin startproject mysite #mysite是创建的工程名称,django-admin其实是django-admin.py是Django的管理工具。
cd mysite #进入项目目录
python manage.py runserver 0.0.0.0:8000 #启动django项目,如果不指定端口默认启动端口为127.0.0.1:8000端口
#上图说明启动没有问题。
#浏览器访问以下是成功的没问题。
1.4 目录介绍
目录说明:
mysite #项目的容器。 mysite #创建的app manage.py #一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。 mysite/__init__.py #一个空文件,告诉Python该目录是一个Python包。python3里面可以不存在,但是python2里面要存在,这样才会把目录认为是python的包而不是普通的目录 mysite/settings.py #该 Django 项目的设置/配置。 mysite/urls.py #URL对应关系,url与一个函数的对应关系,保存了好多个对应关系,请求过来如果查询成功,触发函数并返回结果 mysite/wsgi.py #一个 WSGI兼容的Web服务器的入口,uwsgi + nginx 。 - manage.py # 管理Django程序: - python manage.py - python manage.py startapp xx #创建app - python manage.py makemigrations #自带的orm框架 - python manage.py migrate #这条命令的主要作用就是把这些改动作用到数据库也就是执行migrations里面新改动的迁移文件更新数据库,比如创建数据表,或者增加字段属性 - python manage.py flush #清空数据库,此命令会询问是 yes 还是 no, 选择 yes 会把数据全部清空掉,只留下空表。 - python manage.py createsuperuser #创建超级用户, 按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填 - python manage.py changepassword username #修改用户名密码 - python manage.py shell #Django项目终端,这个命令和 直接运行 python 进入 shell 的区别是:你可以在这个 shell 里面调用当前项目的 models.py 中的 API,对于操作数据的测试非常方便。 - python manage.py dbshell #Django项目环境终端,Django 会自动进入在settings.py中设置的数据库,如果是 MySQL 或 postgreSQL,会要求输入数据库用户密码。在这个终端可以执行数据库的SQL语句。
1.5 视图和 URL 配置
在主站下面创建一个views.py,这就是试图文件:
from django.shortcuts import HttpResponse # Create your views here. def home(request): return HttpResponse('<h1>CMDB</h1>') def hello(request): return HttpResponse("Hello world! xiao huo!")
在主站下面的urls.py的配置:
from django.contrib import admin from django.urls import path from django.conf.urls import url from . import views import time urlpatterns = [ path('admin/', admin.site.urls), url(r'^home/',views.home), #如果访问的是home开头/的就指向views文件下面的home函数 url(r'^$', views.hello), #如果是根目录的url就返回views目录下的hello函数 ]
#课件url是Django的分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应地Model和Template。
注意:项目中如果代码有改动,服务器会自动监测代码的改动并自动重新载入,所以如果你已经启动了服务器则不需手动重启。
Django url() 可以接收四个参数,分别是两个必选参数:regex、view 和两个可选参数:kwargs、name,接下来详细介绍这四个参数。
regex #正则表达式,与之匹配的 URL 会执行对应的第二个参数 view。 view #用于执行与正则表达式匹配的 URL 请求。 kwargs #视图使用的字典类型的参数。 name #用来反向获取 URL。
1.6 创建多个app
当我写一个运维平台的是,可能会有很多的模块,那么每个模块我们叫做一个app,这样就实现了代码分离,数据库共享的效果!
cd mysite
python manage.py startapp cmdb #这是创建了两个app,一个cmdb一个openstack
python manage.py startapp openstack
app目录介绍:
|--migrations 数据库操作记录目录 --__init__.py --admin.py #django后台管理配置 --apps.py # 配置当前app --models.py #django后台管理数据库表管理文件,创建指定的类,models可以创建表结构 --tests.py #单元测试 --views.py #写和当前app相关的所有业务代码
主站也就是mysite目录下的设置:
urls.py:
from django.conf.urls import url,include from django.contrib import admin from . import views urlpatterns = [ url(r'^$',views.index), url(r'^openstack/',include('openstack.urls')), #如果是以openstack或者cmdb为根目录后缀的就给转到对应的目录下的urls文件。 url(r'^cmdb/',include('cmdb.urls')), ]
#注意但是在django新版本已经不支持上面的写法了换成下面的了:
from django.urls import path, include, re_path from . import views from django.contrib import admin urlpatterns = [ path('admin/', admin.site.urls), path('',views.index), path('cmdb/',include('cmdb.urls')), ]
views.py:
from django.shortcuts import HttpResponse def index(request): return HttpResponse("Hello world!")
cmdb目录下的设置:
urls.py:
from django.conf.urls import url,include from django.contrib import admin from . import views urlpatterns = [ #这样就可以自己定义url指向了 url(r'^home/',views.home), url(r'^$', views.hello), ]
#新版本换成了下面的写法要注意哈:
from django.urls import path, include, re_path from django.contrib import admin from . import views urlpatterns = [ path('home/',views.home), path('', views.hello), ]
views.py:
from django.shortcuts import HttpResponse # Create your views here. def home(request): return HttpResponse('<h2>CMDB.cmdb</h2>') def hello(request): return HttpResponse("Hello world! xiao huo!I am is cmdb.")
openstack目录下的设置:
urls.py:
from django.conf.urls import url,include from django.contrib import admin from . import views urlpatterns = [ url(r'^home/',views.home), url(r'^$', views.hello), ]
views.py:
from django.shortcuts import HttpResponse # Create your views here. def home(request): return HttpResponse('<h2>openstack.openstack</h2>') def hello(request): return HttpResponse("Hello world! xiao huo!I am is openstack.")
#可以看到127.0.0.1:8000/后面的后缀不一样,输出也不一样。
1.7 models.py配置
models.py是Django中的数据库模型类。
配置文件设置:
settings.py:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'cmdb', #如果我们在cmdb下面配置了modles.py要在这里添加 'openstack', #将这两个app添加上 ]
settings.py(默认是本地的sqlite3数据库):
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
如果是mysql的设置就是下面的设置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'django', #数据库名称需要提前创建 'USER': 'root', 'PASSWORD': '123456', 'HOST': '192.168.1.108', 'PORT': '3306', } }
#Django内部连接mysql的第三方工具是MySQLDB,但是python3不再支持MySQLDB,所以得修改django默认连接mysql方式为pymysql,修改项目同名文件下__init__.py文件pymsql替换内部的myqldb,修改django默认连接mysql第三方工具:
import pymysql pymysql.install_as_MySQLdb()
urls.py配置:
url(r'^admin/', admin.site.urls), #配置后台管理url
models.py配置:
from django.db import models class UserType(models.Model): name = models.CharField(max_length=32) #name是字段,CharField 用于存储字符串,max_length设置最大长度 class UserInfo(models.Model): username = models.CharField(max_length=32) pwd = models.CharField(max_length=32) email = models.CharField(max_length=32) user_type = models.ForeignKey(UserType, on_delete=models.CASCADE) #一个表中的 FOREIGN KEY 指向另一个表中的 PRIMARY KEY。
admin.py配置:
Django自带的后台管理是Django明显特色之一,可以让我们快速便捷管理数据。后台管理可以在各个app的admin.py文件中进行控制。
from django.contrib import admin from cmdb import models # Register your models here admin.site.register(models.UserInfo) #在admin中注册绑定, admin.site.register(models.UserType)
执行命令:
python manage.py makemigrations
#相当于 在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py, 但是这个改动还没有作用到数据库文件,可以手动打开这个文件,看看里面是什么。
python manage.py migrate
#python manage.py migrate将该改动作用到数据库文件,比如产生table之类
python manage.py createsuperuser
#Django 创建超级管理员
启动服务并查看:
python manage.py runserver 0.0.0.0:8000
访问url: 127.0.0.1:8000/admin
#如果admin密码忘记了,可以
python manage.py shell
然后获取你的用户名,并且重设密码:
from django.contrib.auth.models import User user = User.objects.get(username='admin') user.set_password('new_password') user.save()
#做完上面的操作就可以用新密码登录了。
1.8 static配置
网站通常需要增加图片、JavaScript、或者CSS等文件提供服务。在Django中,我们把这些文件称为“静态文件”(static files)。Django提供django.contrib.staticfiles来帮助你管理他们。
主站的settings.py设置:
STATIC_URL = '/static/' #引用名,默认的不用改 STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), #实际名 ,即实际文件夹的名字 ) #django对引用名和实际名进行映射,引用时,只能按照引用名来,不能按实际名去找,所以这里实际名和引用名就创建的一致了。
#注,如果是statics文件夹写在不同的app下,静态文件的调用:
STATIC_URL = '/static/' STATICFILES_DIRS=( ('hello',os.path.join(BASE_DIR,"app01","statics")) , ) #<script src="/static/hello/jquery-1.8.2.min.js"></script>
1.9 template(模板)配置
为什么用templates?
对页面设计进行的任何改变都必须对 Python views.py中的代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。 Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。 程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。 #基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式。
主站目录下的settings.py下面设置:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] ##加上了这句话,定义了模板的位置目录为templates,如果没有这句话的话
#还有就是又一个地方要暂时注释掉,不然提交表单会有403报错信息(CSRF verification failed. Request aborted.):
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', #这里暂时注释掉 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
#不注释掉就是上图的报错。这是因为,有一个真正的跨站请求伪造,或当Django的CSRF的机制还没有正确使用。这里先不搞CSRF的设置,先注释掉。
下面是静态文件的创建:
#jquery.min.js是网上下载的jQuery 是一个 JavaScript 库。
commons.css设置(先搞个背景颜色):
body{ background: #eeeeee; }
login.html的设置:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/commons.css" /> <style> label{ width: 80px; text-align: right; display: inline-block; } </style> </head> <body> <form action="/cmdb/login" method="post"> <p> <label for="username">用户名:</label> <input id="username" name="user" type="text" /> </p> <p> <label for="password">密码:</label> <input id="password" name="pwd" type="password" /> <input type="submit" value="提交" /> <span style="color: red;">{{ error_msg }}</span> </p> </form> <script src="/static/jquery.min.js"></script> </body> </html>
#主要是注意{{ error_msg }},这叫模板的渲染,这是一个变量,django会浏览html页面如果里面有{{}}抱起来的变量,视图函数返回数据之前,会将值传递过来替换掉。
#注意表单里面要提交的元素都要有name,这样django才能抓到元素的值。
cmdb目录下的设置:
urls.py设置:
urlpatterns = [ url(r'^home/',views.home), url(r'^$', views.hello), url(r'^login', views.login), #加一条login登录url ]
#注意: url(r'^login/', views.login), #如果加了/,html页面的action那里后缀也要加上/,保持一致。
views.py设置:
from django.shortcuts import HttpResponse from django.shortcuts import render from django.shortcuts import redirect def login(request): # 包含用户提交的所有信息 # 获取用户提交方法 # print(request.method) error_msg = "" if request.method == "POST": # 获取用户通过POST提交过来的数据 user = request.POST.get('user',None) #这样如果用户名或者密码是空值,默认就是None,不会报错。 pwd = request.POST.get('pwd',None) #如果是GET方法提交的数据呢,就是pwd = request.GET.get('pwd',None) if user == 'root' and pwd == "123456": # 去跳转到 return redirect('/cmdb/home') #redirect后面是127.0.0.1:8000后面的url #return redirect(' #注意如果你要跳转到外网一定要在前面加上http://,如果不加就会将你这个url就会变成127.0.0.1:8000/cmdb(就是当前的app名称)/www.baidu.com else: # 用户密码不配 error_msg = "用户名或密码错误" return render(request,'login.html', {'error_msg': error_msg}) #将error_msg所代表的值传递给login.html里面的'error_msg'字段,可见render是返回一个页面文件
#上面之所以可以找到login.html没有报错,是因为我们定义了template。
测试一下:
账号密码正确的测试:
账号密码错误的测试:
#django返回数据的时候如果返回一个html的时候,我们的想法是,打开一个html读出数据来,把整个数据返回给客户端,但是这种模式假如有好多访问需要不断的我们来打开文件,这样很麻烦;django后来给我们封装了一个方法我们引入render这个方法进行返回就行了,其实他内部也是打开返回这么操作的。
from django.shortcuts import render
假如我们要重定向到另外一个url的时候:就需要引入我redirect这个方法进行返回
from django.shortcuts import redirect
https://www.cnblogs.com/sunqim16/p/7113477.html #一张博客总结的挺全乎
官网关于setting配置文件设置的介绍:https://docs.djangoproject.com/en/2.0/ref/settings/
1.10 获取request
来看看request里面有什么?
#先获取下request类型 def index(request): print(type(request)) return HttpResponse('OK')
#request对象就是根据这个类创建的,POST、GET等都在里面又定义
from django.core.handlers.wsgi import WSGIRequest def index(request): print(type(request)) print(request.environ) #打印一下request.environ 封装了所有用户请求信息都是原生的数据 return HttpResponse('OK')
#django会帮拿到这些信息并处理,其他的就要自己处理了。
from django.core.handlers.wsgi import WSGIRequest def index(request): for k,v in request.environ.items(): print(k,v) return HttpResponse('OK')
#来获取一下request.environ里面都有用户上传的哪些信息:
ALLUSERSPROFILE C:\ProgramData APPDATA C:\Users\admin\AppData\Roaming COMMONPROGRAMFILES C:\Program Files\Common Files ...... HTTP_HOST 127.0.0.1:8000 HTTP_CONNECTION keep-alive HTTP_CACHE_CONTROL max-age=0 HTTP_USER_AGENT Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
抓取我们想要的数据:
from django.core.handlers.wsgi import WSGIRequest def index(request): print(request.environ['HTTP_USER_AGENT']) #可以这样抓一下 return HttpResponse('OK')
#这样user_agent的信息就抓到了。