目录
一、框架介绍
ORM框架
Django中内嵌了ORM框架,ORM框架可以将类和数据表进行对应起来,只需要通过类和对象就可以对数据表进行操作。
设计类:模型类
ORM另一个作用:根据设计的类生成数据库中的表。
Django架构之MVT
二、框架搭建
首先需要安装django模块
pip install django
或者使用镜像下载
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com 包名
pip install 包名 -i https://pypi.douban.com/simple
1、创建项目
django-admin startproject 项目名
__init__.py 说明JangoDemo 是一个Python包
settings.py 项目的配置文件
urls.py 进行url路由的配置
wsgi.py 服务器和Django交互的入口
manage.py 项目的管理文件
2、创建应用(模块)
cd 项目名
python manage.py startapp 应用名
注册应用
在settings.py建立项目与应用的联系
INSTALLED_APPS中加上应用名,如下图
3、启动项目
python manage.py runserver
或
python3 manage.py runserver 0.0.0.0:8000
默认访问地址为http://127.0.0.1:8000/
三、模型 - Model
模型类设计 - 创建实体类
在models.py中编辑如下
from django.db import models
# Create your models here.
# 设计和表对应的类,模型类
# 图书类
class BookInfo(models.Model):
'''
图书模型类
模型类要继承Model
'''
btitle = models.CharField(max_length=20) # 图书名称
bpub_date = models.DateField() # 出版日期
# 改变后台管理页面的数据对象的名字,重写方法
def __str__(self):
# 返回书名
return self.btitle
'''
英雄人物模型
英雄名 hname
性别 hgender
年龄 hage
备注 hcomment
关系属性 hbook 建立图书类(一类)和英雄人物类(多类)之间的一对多关系
'''
class HeroInfo(models.Model):
hname = models.CharField(max_length=20)
hgender = models.BooleanField(default=False) # false代表男
hcomment = models.CharField(max_length=128)
# 关系属性对应表的字段名格式:关系属性名_id 是外键,对应BookInfo表的id值
hbook = models.ForeignKey('BookInfo',on_delete=models.CASCADE) # 多类中定义关系属性
# 改变后台管理页面的数据对象的名字,重写方法
def __str__(self):
# 返回书名
return self.hname
模型类生成表
执行命令:
# 生成迁移文件(默认使用的数据库 sqlite3)
python manage.py makemigrations
# 执行迁移生成表
python manage.py migrate
说明:
生成的默认表名为:应用名_模型类名
通过模型类操作数据表
说明:
想要在shell中操作django的模型数据,必须执行python manage.py shell
# 打开shell
python manage.py shell
以下为在shell中端演示的例子:
# 首先导入模型类
from app1.models import BookInfo,HeroInfo1)向app1_bookinfo表中插入一条数据。
b=BookInfo() # 定义一个BookInfo对象
b.btitle='天龙八部'
from datetime import date
b.bpub_date=date(1990,1,1)
b.save() # 保存数据2)查询出app1_bookinfo表中id为1的数据。
b1=BookInfo.objects.get(id=1)3)在上一步的基础上改变id为1的数据对应的图书出版日期字段。
b1.bpub_date=date(1990,10,10)
b1.save() # 更新数据4)接着,删除数据。
b1.delete() # 删除id=1的那条数据5)向app1_heroinfo表中插入一条数据。
h = HeroInfo()
h.hname = '郭靖'
h.hgender = 'False'
h.hcomment = '降龙十八掌'
b2=BookInfo.objects.get(id=1)
h.hbook = b2 # 给关系属性赋值,英雄对象所属的图书对象
h.save()6)查询图书表里面的所有内容。
BookInfo.objects.all()
HeroInfo.objects.all()# 查看单个属性
h.hbook_id # 1
h.hbook # <BookInfo: BookInfo object>
h.hbook.btitle # '天龙八部'
关系操作:
# 查询图书关联的英雄信息
b.heroinfo_set.all() # [<HeroInfo: HeroInfo object> <HeroInfo: HeroInfo object>]# 查询出id为2的图书中所有的英雄人物的信息。
BookInfo.objects.get(id=2).heroinfo_set.all() # [<HeroInfo: HeroInfo object> <HeroInfo: HeroInfo object>]
四、后台管理
1)本地化
语言和时区的本地化
修改settings.py文件
LANGUAGE_CODE = 'zh-hans' # 使用中文
TIME_ZONE = 'Asia/Shanghai' # 中国时间
2)创建管理员,并设置用户名和密码(这里我设置的是admin、admin)
命令:python manage.py createsuperuser
3) 访问页面 http://127.0.0.1:8000/admin/
登录之后,但是页面没有任何数据。
4)注册模型类
在应用下的admin.py中注册模型类
告诉Django框架根据注册的模型类来生成对应表管理页面,页面就有模型类了。
from django.contrib import admin
from .models import BookInfo,HeroInfo
# 后台管理相关文件
# Register your models here.
# 注册模型类
admin.site.register(BookInfo)
admin.site.register(HeroInfo)
页面效果如下:
5)自定义管理页面
自定义模型管理类。模型管理类就是告诉Django在生成的管理页面上显示哪些内容。
from django.contrib import admin
from .models import BookInfo,HeroInfo
# 后台管理相关文件
# Register your models here.
# 自定义模型管理类 类名自定义
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)
页面效果如下:
五、视图 - View
在Django中,通过浏览器去请求一个页面时,使用视图函数来处理这个请求的,视图函数处理之后,要给浏览器返回页面内容。
视图函数的使用
1、定义视图函数
视图函数定义在views.py中
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
# 1.定义视图函数,HttpRequest
# 2.进行url配置,建立url地址和视图的对应关系
# http://127.0.0.1:8000/index
def index(request):
# 进行处理,和M、T进行交互
return HttpResponse('hello,word')
说明:
def index(request):
# 进行处理。。。
return HttpResponse('hello python')
视图函数必须有一个参数request,进行处理之后,需要返回一个HttpResponse的类对象,hello python就是返回给浏览器显示的内容。
2、在应用下创建urls.py
在应用下新建python文件,名为urls.py。
3、在应用下的urls文件下配置路由
from django.conf.urls import url, include
from . import views
urlpatterns = [
# 通过url函数设置url路由配置项
# 1.严格匹配开头和结尾
url(r'^index$', views.index), # 建立/index和视图index之间的关系
]
说明:
所有的url配置项都定义在urlpatterns的列表中。
配置url时,有两种语法格式:
a) url(正则表达式,视图函数名)
b) url(正则表达式, include(应用中的urls文件))
4、配置项目下的urls文件
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
# 项目的urls文件
urlpatterns = [
path('admin/', admin.site.urls), # 项目配置(默认有)
url(r'^', include('app1.urls')), # 包含app1应用中的urls文件
]
访问url
访问http://127.0.0.1:8000/index
url匹配的过程说明
在项目的urls.py文件中包含具体应用的urls.py文件,应用的urls.py文件中写url和视图函数的对应关系。
比如,当用户输入http://127.0.0.1:8000/aindex时,去除域名和最前面的/,剩下aindex,拿aindex字符串到项目的urls文件中进行匹配,匹配成功后,去除匹配的a字符,拿剩下的index字符串继续到项目的urls文件中进行正则匹配,匹配成功之后执行视图函数index,index视图函数返回内容hello python给浏览器来显示。
六、模板 - Templates
模板不仅仅是一个html文件,可以用变量进行替换,也可以写类似编程语言的代码。
模板文件的使用
1、创建模板文件夹
在项目下创建文件夹templates。
为了使一个应用对应一个模板文件,可以在templates文件夹下新建一个文件夹app1作为应用app1的模板文件。
2、配置模板文件
在settings文件中的TEMPLATES配置项中配置如下
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 设置模板文件目录
说明:
BASE_DIR是项目目录的绝对路径
3、使用模板文件
a) 加载模板文件
去模板目录下面获取html文件的内容,得到一个模板对象。
b) 定义模板上下文
向模板文件传递数据。
c) 模板渲染
得到一个标准的html内容。
- 在tmplates/app1下创建一个index.html文件,并编辑
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板文件</title>
</head>
<body>
<h1>这是一个模板文件</h1>
使用模板变量:<br/>
{{ content }}<br/>
使用列表:<br/>
{{ list }}<br/>
for循环:<br/>
<ul>
{% for i in list %}
<li>{{ i }}</li>
{% endfor %}
</ul>
</body>
</html>
4、视图调用
from django.shortcuts import render
# from django.http import HttpResponse
# from django.template import loader, RequestContext
# Create your views here.
# 1.定义视图函数,HttpRequest
# 2.进行url配置,建立url地址和视图的对应关系
# http://127.0.0.1:8000/index
def index(request):
# 进行处理,和M、T进行交互
# return HttpResponse('hello,word')
# # 使用模板文件
# # 1.加载模板文件, 返回值是一个模板对象
# temp = loader.get_template('app1/index.html')
# # 2.定义模板上下文:给模板文件传递数据
# context = RequestContext(request, {}) # {}里存放字典数据
# # 3.模板渲染:产生标注的html内容
# res_html = temp.render(context)
# # 4.返回给浏览器
# return HttpResponse(res_html)
# render的参数:request,模板文件,模版变量字典
return render(request, 'app1/index.html',
{'content':'hello world', 'list':list(range(1, 10))})
访问页面
给模板文件传递数据
模板变量使用:{{ 模板变量名}}
模板代码段:{% 代码段 %}
for循环:
{% for i in list %}
{% endfor %}
七、完成一个案例
案例效果
编码之前的准备工作
1)设计出访问页面的url和对应的视图函数的名字,确定视图函数的功能。
2)设计模板文件的名字。
以下为案例中的简单设计过程:
1)完成图书信息的展示:
a) 设计url,通过浏览器访问http://127.0.0.1:8000/books时显示图书信息页面。
b) 设计url对应的视图函数 show_books。
查询出所有图书的信息,将这些信息传递给模板文件。
c) 编写模板文件 show_books.html。
遍历显示出每一本图书的信息。
2)完成点击某本图书时,显示出图书里所有英雄信息的页面。
a) 设计url,通过访问http://127.0.0.1:8000/books/数字时显示对应的英雄信息页面。
这里数字指点击图书的id。
b) 设计对应的视图函数detail。
接收图书的id,根据id查询出相应的图书信息,然后查询出图书中的所有英雄信息。
c) 编写模版文件detail.html。
说明:
<ul> {% for hero in heros %} <li>{{ hero.hname }}--{{ hero.hcomment }}</li> {% empty %} <li>没有英雄信息</li> {% endfor %} </ul>
在django里称为模版标签,上述指如果遍历没有数据则执行empty的内容。
完整代码
说明:
1、本案例代码后续功能是在本文章前面介绍的代码基础上继续增加功能。
2、另外数据库中的书名“神雕侠侣”是直接在http://127.0.0.1:8000/admin/页面中添加的,此处没有写出来。(需要自行添加一条数据)
- 项目目录结构
- 应用下的urls.py文件代码
#!/usr/bin/python
# -*- coding:utf-8 -*-
from django.conf.urls import url, include
from . import views
'''
url(r'^books/(\d+)$', views.detail)
在\d+两边加(),让它变成一个组。Django会自动把组里的数据作为参数传递给视图函数
'''
urlpatterns = [
# 通过url函数设置url路由配置项
# 1.严格匹配开头和结尾
url(r'^index$', views.index), # 建立/index和视图index之间的关系
url(r'^books$', views.show_books), # 显示图书信息
url(r'^books/(\d+)$', views.detail), # 显示英雄信息
]
- views.py文件代码
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader,RequestContext
from .models import BookInfo
# Create your views here.
# 1.定义视图函数,HttpRequest
# 2.进行url配置,建立url地址和视图的对应关系
# http://127.0.0.1:8000/index
# def index(request):
# # 进行处理,和M、T进行交互
# return HttpResponse('hello,word')
def index(request):
# 进行处理,和M、T进行交互
# return HttpResponse('hello,word')
# # 使用模板文件
# # 1.加载模板文件, 返回值是一个模板对象
# temp = loader.get_template('app1/index.html')
# # 2.定义模板上下文:给模板文件传递数据
# context = RequestContext(request, {})
# # 3.模板渲染:产生标注的html内容
# res_html = temp.render(context)
# # 4.返回给浏览器
# return HttpResponse(res_html)
# render的参数:request,模板文件,变量字典
return render(request, 'app1/index.html',
{'content': 'hello world', 'list': list(range(1, 10))})
def show_books(request):
'''显示图书的信息'''
# 1、通过M查找图书表中的数据
books = BookInfo.objects.all()
# 2、使用模版
return render(request, 'app1/show_books.html', {'books': books})
def detail(request, bid):
'''查询图书关联的英雄信息'''
# 1、根据bid查询图书信息
book = BookInfo.objects.get(id=bid)
# 2、查询和book关联的英雄信息
heros = book.heroinfo_set.all()
# 3、使用模版
return render(request, 'app1/detail.html', {'book': book, 'heros': heros})
- show_books.html文件代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>显示图书信息</title>
</head>
<body>
图书内容如下:
<ul>
{% for book in books %}
<li><a href="/books/{{ book.id }}">{{ book.btitle }}</a></li>
{% endfor %}
</ul>
</body>
</html>
- detail.html文件代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>查询图书关联的英雄信息</title>
</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>