#4. 虚拟环境 ##4.1 概念 以前安装python包的命令: sudo pip3 install 包名 包的安装路径:/usr/local/lib/python3.5/dist-packagescss
在同一个python环境中安装同一个包的不一样版本,后安装的包会把原来安装的包覆盖掉。这样,若是同一台机器上两个项目依赖于相同包的不一样版本,则会致使一些项目运行失败。 解决的方案就是:虚拟环境。
虚拟环境是真实python环境的复制版本。 在虚拟环境中使用的python是复制的python,安装python包也是安装在复制的python中。 ##4.2 安装和配置 安装虚拟环境的命令:html
- 1)sudo pip install virtualenv #安装虚拟环境
- 2)sudo pip install virtualenvwrapper #安装虚拟环境扩展包
- 3)编辑/home目录下面的.bashrc文件,添加下面两行。
export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh
-
4)使用source .bashrc使其生效一下。 ##4.3 使用python
-
建立虚拟环境命令:mkvirtualenv 虚拟环境名mysql
-
建立python3虚拟环境:mkvirtualenv -p python3 evn_py3web
- 建立python3虚拟环境名,# 在建立虚拟环境时,必须保证有网
-
进入虚拟环境工做:workon 虚拟环境名正则表达式
-
查看机器上有多少个虚拟环境:workon 空格 + 两个tab键sql
-
退出虚拟环境:deactivateshell
-
删除虚拟环境:rmvirtualenv 虚拟环境名数据库
-
虚拟环境下安装包的命令:pip install 包名
注意:不能使用sudo pip install 包名,这个命令会把包安装到真实的主机环境上而不是安装到虚拟环境中。django -
查看虚拟环境中安装了哪些python包:
pip list pip freeze
- 安装django环境:pip install django==3.0.3
- 若是网很差,会报错:在python中安装包出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))
-- 参考连接1
pip install django==3.0.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
拓展: apt-get install 软件 pip install python包名 #5. 项目建立 ##5.1 建立Django项目
-
命令:django-admin startproject 项目名(test1)
注意:建立应用必须先进入虚拟环境。
-
tree可查看项目目录
-
项目目录以下:
- __init__.py: 说明test1是一个python包。
- settings.py: 项目的配置文件。
- urls.py: 进行url路由的配置。
- wsgi.py: web服务器和Django交互的入口。
- manage.py: 项目的管理文件。 ##5.2 建立Django应用 一个项目由不少个应用组成的,每个应用完成一个功能模块。
-
建立应用的命令以下:python manage.py startapp 应用名(booktest) 注意:建立应用时须要先进入项目目录。
-
应用目录以下:
-
__init__.py: 说明目录是一个Python模块。
-
models.py: 写和数据库项目的内容, 设计模型类。
-
views.py: 接收请求,进行处理,与M和T进行交互,返回应答。定义处理函数,视图函数。
- 定义处理函数,视图函数---相对于mini-web中的处理函数 def def add_focus(ret): # 1. 获取股票代码
-
tests.py: 写测试代码的文件。
-
admin.py: 网站后台管理相关的文件。
##5.3 应用注册 创建应用和项目之间的联系,须要对应用进行注册,修改settings.py中的INSTALLED_APPS配置项。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'booktest' #加入'booktest', # 进行应用的注册 ]
##5.4 启动项目
- 运行开发web服务器命令:python manage.py runserver
- 使用Django中内置的服务器:python manage.py runserver
- 复制文件中的http://127.0.0.1:8000/到浏览器并打开(或192.168.x.xx:xxxx)
- 若是是虚拟机中,可能出现:主机没法访问虚拟机中运行的Django项目
- 运行Django的命令,要写成: python3 manage.py runserver 0.0.0.0:8000 ,重点就是这个0.0.0.0,这样才能让外部访问到
- 参考连接2
- 若是出现:Invalid HTTP_HOST header: '192.168.1.111:8000'. You may need to add '192.168.1.111' to ALLOWED_HOSTS
- 在咱们建立的项目里修改setting.py文件 ALLOWED_HOSTS = ['*'] #在这里请求的host添加了*
- 参考连接3
- 复制文件中的http://127.0.0.1:8000/到浏览器并打开(或192.168.x.xx:xxxx)
#6. 模型类 ##6.1 ORM
django中内嵌了ORM框架,ORM框架能够将类和数据表进行对应起来,只须要经过类和对象就能够对数据表进行操做。
- 在Django中主要是 设计类:模型类。
- 在models.py文件中填写 ORM另一个做用:根据设计的类生成数据库中的表。
##6.2 模型类设计 在应用models.py中设计模型类,必须继承于models.Model类。
- 1) 设计BookInfo类。
- 2) 设计HeroInfo类。 Models.ForeignKey能够创建两个模型类之间一对多的关系,django在生成表的时候,就会在多端的表中建立一列做为外键,创建两个表之间一对多的关系。
##6.3 模型类生成表
-
- 生成迁移文件
- 命令:python manage.py makemigrations 迁移文件是根据模型类生成的。
-
- 执行迁移生成表
- 命令:python mange.py migrate 根据迁移文件生成表。 生成表名的默认格式: 应用名_模型类名小写
- 3)安装sqliteman:sudo apt-get install sqliteman 安装失败,更换源
- 根据迁移文件生成表,生成表名的默认格式: 应用名_模型类名小写
##6.4 经过模型类操做数据表
- 进入项目shell的命令: python manage.py shell 如下为在相互shell终端中演示的例子:
- 首先导入模型类:
> from booktest.models import BookInfo,HeroInfo #1) 向booktest_bookinfo表中插入一条数据。 b = BookInfo() #定义一个BookInfo类的对象 b.btitle ='天龙八部' #定义b对象的属性并赋值 b.bpub_date = date(1990,10,11) b.save() #才会将数据保存进数据库 #2) 查询出booktest_bookinfo表中id为1的数据。 b = BookInfo.objects.get(id=1) #3) 在上一步的基础上改变b对应图书的出版日期。 b.bpub_date = date(1989,10,21) b.save() #才会更新表格中的数据 #4) 紧接上一步,删除b对应的图书的数据。 b.delete() #才会删除 #5) 向booktest_heroInfo表中插入一条数据。 h = HeroInfo() h.hname = '郭靖' h.hgender = False h.hcomment = ‘降龙十八掌’ b2 = BookInfo.objects.get(id=2) h.hbook = b2 #给关系属性赋值,英雄对象所属的图书对象 h.save() #6) 查询图书表里面的全部内容。 BookInfo.objects.all() HeroInfo.objects.all()
###6.4.1. models.py中:
from django.db import models # 设计和表对应的类,模型类 # Create your models here. # 一类 # 图书类 class BookInfo(models.Model): # 要继承models.Model之后,才是一个模型类 # '''图书模型类''' # 图书名称,Charfield说明是一个字符串,max_length指定字符串的最大长度 btitle = models.CharField(max_length=20) # 出版日期,DateField说明是一个日期类型 bpub_date = models.DateField() # 生成的db.sqlite3能够用sudo apt-get install sqliteman后,打开 # django默认sqlite小型数据库,要替换成mysql # 多类 # 英雄人物类 # 英雄名 name # 性别 hgender # 年龄 hage # 备注 hcomment # 关系属性 hbook,创建图书类和英雄人物类之间的一对多关系 class HeroInfo(models.Model): # '''英雄人物模型类''' hname = models.CharField(max_length=20) # 英雄名称 # 性别,BooleanField说明是bool类型,default指定默认值,False表明男 hgender = models.BooleanField(default=False) # 备注 hcomment = models.CharField(max_length=128) # 关系属性 hbook,创建图书类和英雄人物类之间的一对多关系 # 关系属性对应的表的字段名格式: 关系属性名_id hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE,) # ForeignKey外键 # 经过模型类操做数据表 # 进入项目shell的命令:python manage.py shell # # 增长实例属性要和类属性名称同样
##6.5 关联操做
###1) 查询出id为2的图书中全部英雄人物的信息。
b = BookInfo.objects.get(id=2) b.heroinfo_set.all() #查询出b图书中全部英雄人物的信息
#7. 后台管理
##1) 本地化
- 语言和时区的本地化。
- 修改settings.py文件。
# LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'zh-hans' # 使用中文 # TIME_ZONE = 'UTC' TIME_ZONE = 'Asia/Shanghai' # 中国时间
##2) 建立管理员
- 命令:python manage.py createsuperuser
- 执行时,可能会报错:Django项目出现: 禁止访问(403),CSRF验证失败,相应中断
- 解决办法:在app的views.py 文件中能够添加一个 from django.template import RequestContext 而后,渲染函数render 添加便可。
- 如: return render(request, ‘users/register.html’,context={‘form’:form})
- 参考连接7.2
##3) 注册模型类 在应用下的admin.py中注册模型类,告诉djang框架根据注册的模型类来生成对应表管理页面。
from booktest.models import BookInfo, HeroInfo admin.site.register(BookInfo) admin.site.register(HeroInfo)
- __str__:若是一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值
- models.py中:重写一个__str__方法
class BookInfo(models.Model): """图书模型类""" ... def \_\_str__(self): # 返回英雄名 return self.hname
##4) 自定义管理页面 自定义模型管理类:模型管理类就是告诉django在生成的管理页面上显示哪些内容。
class BookInfoAdmin(admin.ModelAdmin): """图书模型管理类""" list_display = ['id', 'btitle', 'bpub_date'] class HeroInfoAdmin(admin.ModelAdmin): """英雄人物管理类""" list_display = ['id', 'hname', 'hcomment'] # 注册模型类 admin.site.register(BookInfo, BookInfoAdmin) admin.site.register(HeroInfo, HeroInfoAdmin)
#8. 视图 在Django中,经过浏览器去请求一个页面时,使用视图函数来处理这个请求的,视图函数处理以后,要给浏览器返回页面内容。 ##8.1视图函数的使用 ###1) 定义视图函数 视图函数定义在views.py中。
- 例:
def index(request): #进行处理。。。 return HttpResponse('hello python')
视图函数必须有一个参数request,进行处理以后,须要返回一个HttpResponse的类对象,hello python就是返回给浏览器显示的内容。 ###2) 进行url配置---项目文件夹(test1)下的urls.py url配置的目的是让创建url和视图函数的对应关系。url配置项定义在urlpatterns的列表中,每个配置项都调用url函数。 url函数有两个参数,第一个参数是一个正则表达式,第二个是对应的处理动做。
- 配置url时,有两种语法格式:
- a) url(正则表达式,视图函数名)
- b) url(正则表达式,include(应用中的urls文件))
- 工做中在配置url时,首先在项目的urls.py文件中添加配置项,
- 但并不写具体的url和视图函数之间的对应关系,而是写包含具体应用的urls.py文件,
- 而后,在应用的urls.py文件中写url和视图函数的对应关系。 ##8.2 url匹配的过程
在项目的/test1/urls.py文件中包含具体应用的urls.py文件,应用的/booktest/urls.py文件中写url和视图函数的对应关系。
urlpatterns = [ url(r'^admin/', admin.site.urls), # 配置项目 url(r'^',include('booktest.urls')), # 包含booktest应用中urls # path('admin/', admin.site.urls), ]
- 可能会报错:include()函数报错'provide the namespace argument to include() instead.' % len(arg)
- 解决方案:url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
- 参考连接8.2
# 建议直接将项目test1/urls.py文件的内容,直接复制到应用booktest/urls.py文件中,再将不须要的地方修改掉,这样就不会错了。 """test/urls.py""" from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')), ] # --------------------------------------------------------------------------------- """booktest/urls.py""" from django.conf.urls import url from booktest import views # 建立列表urlpatterns,视图调用就是从这个列表中调用, # 须要经过导入from django.conf.urls import url 来调用项目的urls文件 # 在应用的urls文件中进行url配置的时候: # 1.严格匹配开头和结尾 urlpatterns = [ # 经过url函数设置url路由配置项 url(r'^index$', views.index), # 写入对应的index名字,创建/index和视图index之间的关系 # url(r'^index2', views.index2), # 此时的输入仍是“老铁,没毛病”不对,由于在上一项匹配成功后,就再也不匹配下一项了 url(r'^index2$', views.index2), # 故,为了解决这个问题,需严格匹配开头和结尾,加上^与$ url(r'^books$', views.show_books), # 显示图书信息,即/boos页面显示的内容 url(r'^books/(\d+)$', views.detail), # 显示英雄信息,报错,须要一个bid的位置参数,这时要将\d+做为一个组() ]
8.2.1. 当用户输入如http://127.0.0.1:8000/aindex时,去除域名和最前面的/,剩下aindex,拿aindex字符串
8.2.2. 先到项目的urls文件中进行匹配,配置成功后,去除匹配的a字符,拿剩下的index字符串继续到项目的urls
8.2.3. 文件中进行正则匹配,匹配成功以后执行视图函数index,index视图函数返回内容hello python给浏览器显示
#9. 模板 模板不只仅是一个html文件。 ##9.1 模板文件的使用
- 1 建立模板文件夹:项目test1/下面建立templates文件夹---/test1/templates/
- 2 配置模板目录
- settings.py文件中有TEMPLATES 选项,这个配置就是让咱们去设置模板目录的。
- 在'DIRS': []中设置模板文件的目录,设置路径,可是路径不能随便设置,而应该根据BASE_DIR来设置
- 项目目录的绝对路径,pwd,/home/huang/bj18/test1获得的就是项目目录
- 设置时,将BASE_DIR和模板目录进行拼接
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # 设置模板文件目录,路径 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
-
设置完模板目录后,便可使用,为了给多个应用(booktest等)使用,不混淆,会在模板文件夹(templates)下,再新建同名文件夹booktest,
-
新建模板文件index.html,写好内容后,便可使用模板文件;
-
在mini_frame框架中,手动打开一个文件读取出来,Django中不能这样作,使用模板文件应该遵循如下步骤:
-
3 使用模板文件
- 1.定义视图函数,HttpRequest
- 在booktest下新建一个urls.py
- 视图函数的做用是: 调用模板,处理数据并返回给浏览器。
- 若是须要操做数据库,须要和M、T进行交互
- 2.进行url配置,创建url地址和视图的对应关系,和Flask类似
- 浏览器中输入http:127.0.0.1:8000/index # 用户要显示该url,须要在应用app中的urls列表中,添加该url
- 1.定义视图函数,HttpRequest
from django.shortcuts import render from django.http import HttpResponse from django.template import loader, RequestContext from booktest.models import BookInfo, HeroInfo # 导入模型类 def index(request): ··· return render(request, 'booktest/index.html', {'content': 'hello world', 'list':list(range(1, 10))}, )
urlpatterns = [ url(r'^index$', views.index), # 写入对应的index名字,创建/index和视图index之间的关系 ]
如下a)-c)为视图函数调用模板文件的分析过程,可省略: - 发现除get_template('booktest/index.html')中的'booktest/index.html'、context中的字典不一样外,其他的部分都相同, - 故,从新定义一个函数my_render(),但此方法是多余的,由于已经导入了render,因此能够直接使用 ``` def my_render(request, template_path, context_dict): """使用模板文件""" # 直接将index中的模板文件拿过来使用 # 1.加载模板文件 temp = loader.get_template(template_path) # 写上目录,该目录是相对templetes的目录---改成template_path # 2.定义模板文件上下文:给模板文件传递数据,request,和要传递的数据,经过{}的键值对来传减去 # 导入from django.template import loader, RequestContext # context = RequestContext(request, {''}) # Django1.11之后,就是直接传入{}便可,再也不传入RequestContext(request, {''})---{}字典也改成经过context_dict来改变 # context = {} context = context_dict # 3.模板渲染(目的是把使用的变量,还有一些语句给替换掉):产生标准的html内容,temp中有一个render方法,将context放进去 res_html = temp.render(context) # 4.返回给浏览器 return HttpResponse(res_html) ``` - a)加载模板文件----views.py中,使用模板文件 # 1.加载模板文件 - 导入包 from django.template import loader - temp = loader.get_template('booktest/index.html') # 写上目录,该目录是相对templetes的目录 - b) 定义目标上下文---给模板文件传递定义的变量的值 - 给**模板文件传递数据**:request和要传递的数据,经过{}的键值对来传进去 - 导入from django.template import loader, RequestContext - context = RequestContext(request, {''}) # Django1.11之后,就是直接传入{}便可,再也不传入RequestContext(request, {''}) - \# context = {} - c) 模板渲染(目的是把使用的变量,还有一些语句给替换掉):产生标准的html内容,temp中有一个render方法,将context放进去 - res_html = temp.render(context) - d) 返回给浏览器 - return HttpResponse(res_html)
9.2 给模板文件传递数据
- 模板变量使用:{{ 模板变量名 }}
- 模板代码段:{%代码段%}
- for循环:
{% for i in list %} list不为空时执行的逻辑 {% empty %} list为空时执行的逻辑 {% endfor %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板文件</title> <style type="text/css"> </style> </head> <body> <h1>这是一个模板文件</h1> 使用模板变量:<br/> {{ content }}<br/> 使用列表:<br/> {{ list }}<br/> # 这是直接显示列表的内容,py中还能够遍历出列表中的每个文件 for循环:<br/> <ul> {% for i in list %} <li>{{ i }}</li> {% endfor %} </ul> </body> </html>
#9.3:小结:
- 咱们须要作的事情:
- 1)定义视图函数
- 视图函数定义在views.py中。
- 2)进行url配置,项目视图+应用视图,两个。
- """test/urls.py"""
- """booktest/urls.py"""
- 1)定义视图函数
#10. 案例完成 编码以前的准备工做:
-
1 设计出访问页面的url和对应的视图函数的名字,肯定视图函数的功能。
- def show_books()、detail()
-
2 设计模板文件的名字。
- area.html、index.html
如下为案例中的简单设计过程:
-
1 完成图书信息的展现:
- 1.1 设计url,经过浏览器访问 http://127.0.0.1:8000/books 时显示图书信息页面。
# /test1/urls.py: urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')), ]
#/booktest/urls.py: urlpatterns = [ # 经过url函数设置url路由配置项 url(r'^index$', views.index), url(r'^books$', views.show_books), # 显示图书信息,即/books页面显示的内容 url(r'^books/(\d+)$', views.detail), # 显示英雄信息,报错,须要一个bid的位置参数,这时要将\d+做为一个组() ]
- 1.1 设计url,经过浏览器访问 http://127.0.0.1:8000/books 时显示图书信息页面。
-
1.2 设计url对应的视图函数show_books。
- 查询出全部图书的信息,将这些信息传递给模板文件。
# views.py: import sys from django.shortcuts import render from django.http import HttpResponse from django.template import loader, from booktest.models import BookInfo, HeroInfo # 导入模型类 def show_books(request): """显示图书的信息""" # 1. 经过M查找图书表中的数据 books = BookInfo.objects.all() # 2. 使用模板 return render(request, 'booktest/show_books.html', {'books': books})
- 查询出全部图书的信息,将这些信息传递给模板文件。
-
1.3 编写模板文件show_books.html。
- 遍历显示出每一本图书的信息。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>显示图书信息</title> <style type="text/css"> </style> </head> <body> 图书信息以下: {% for book in books %} <li><a href="/books/{{ book.id }}">{{ book.btitle}}</a></li> {% endfor %} </body> </html>
- 2 完成点击某本图书时,显示出图书里全部英雄信息的页面。
- 2.1 设计url,经过访问http://127.0.0.1:8000/books/数字时显示对应的英雄信息页面。
- 这里数字指点击的图书的id。
url(r'^books/(\d+)$', views.detail), # 显示英雄信息,报错,须要一个bid的位置参数,这时要将\d+做为一个组()
- 这里数字指点击的图书的id。
- 2.2 设计对应的视图函数detail。
- 接收图书的id,根据id查询出相应的图书信息,而后查询出图书中的全部英雄信息。
def detail(request, bid): '''查询图书关联英雄信息''' # 1. 根据bid查询图书信息 book = BookInfo.objects.get(id=bid) # 2. 查询和book关联的信息---要分析1对多(由1查多b.heroinfo_set.all())仍是多对1(h.hbook) # HeroInfo.objects.fliter(hbook__id=1) heros = book.heroinfo_set.all() # 须要显示图书的名字,和关联的英雄名字和备注 # 3. 使用模板detail,建立templates/bootest/detail.html return render(request, 'booktest/detail.html', {'book': book, 'heros': heros}) # 注意,此处是heros,不是hero,否则图书信息就没法显示 # 去应用booktest/urls中设置地址。
- 接收图书的id,根据id查询出相应的图书信息,而后查询出图书中的全部英雄信息。
- 2.3 编写模板文件detail.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>显示图书关联的英雄信息</title> <style type="text/css"> </style> </head> <body> <h1>{{ book.btitle }}</h1> 英雄信息以下:<br/> <ul> {% for hero in heros %} <li>{{ hero.hname }}--{{ hero.hcomment }}</li> {% empty %} <li>没有英雄信息</li> {% endfor %} </ul> </body> </html>
- 2.1 设计url,经过访问http://127.0.0.1:8000/books/数字时显示对应的英雄信息页面。