django概览
下载安装
使用前须知
- 1.计算机的名称不能有中文
- 2.一个pycharm窗口只开一个项目
- 3.项目里面所有的文件也尽量不要出现中文
- 4.python解释器尽量使用3.4~3.6之间的版本
- django版本问题:1.x,2.x,3.x,使用1.x较多(1系列和2系列区别不大)
- djando安装:
pip3 install django==1.11.11
,终端输入django-admin
查看是否安装成功
djando基本操作
提示:下面的操作默认都是基于Django1.11.11版本
命令行操作
# 1.创建django项目
django-admin startproject mysite
#2 切换路径,进入项目,启动项目, 默认ip,port,127.0.0.1:8000
python3 manage.py runserver [ip port]
# 3.创建应用
python manage.py startapp app01
pycharm操作
# 1 new project 选择左侧第二个django即可(专业版pycharm才有)
# 2 启动
1.还是用命令行启动
2.点击绿色小箭头即可
# 3 创建应用
1.pycharm提供的终端直接输入完整命令
2.pycharm
tools > run manage.py task提示(前期不要用 给我背完整命令)
# 4 修改端口号以及创建server
edit > confi....
注意注意1:新建app要到配置文件中注册
创建一个新的应用app,一定要检查配置文件中是否注册了,否则手动注册
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config', # 方式1,写全称(推荐)
'app01', # 方式2,可以简写
]
ps: 你在用pycharm创建项目的时候 pycharm可以帮你创建一个app并且自动注册(前提是你使用了这个自动创建app的功能)。
注意注意2:手动加templates文件夹,需要到配置文件中添加路径
# 1 命令行创建不会自动有templatew文件夹,需要你自己手动创建;
# 2 pycharm会自动帮你创建并且还会自动在配置文件中配置对应的路径
# pycharm创建
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
]
# 命令行创建,DIRS是空的
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
]
"""
也就意味着你在用命令创建django项目的时候不单单需要创建templates文件夹还需要去配置文件中配置路径
'DIRS': [os.path.join(BASE_DIR, 'templates')]
"""
主要文件介绍
-mysite项目文件夹
--mysite文件夹
---settings.py 配置文件
---urls.py 路由与视图函数对应关系(路由层)
---wsgi.py wsgiref模块(不考虑)
--manage.py django的入口文件
--db.sqlite3 django自带的sqlite3数据库(小型数据库 功能不是很多还有bug)
--app01文件夹
---admin.py django后台管理
---apps.py 注册使用
---migrations文件夹 数据库迁移记录
---models.py 数据库相关的 模型类(orm)
---tests.py 测试文件
---views.py 视图函数(视图层)
django三件套
from django.shortcuts import HttpResponse, render, redirect
return HttpResponse('字符串') # 返回字符串
return render(request, 'login.html') # 返回html页面
return redirect(url) # 重定向
补充:视图函数给模板文件传值的方式
- 方式1:构造字典,按需索取
- 方式2:内置函数
locals()
,当前局部变量全部传给模板文件
from django.shortcuts import render
def ab_render(request): # 必须有形参request
user_info = {'name':'xliu', 'age':18}
# 方式1:构造字典
return render(request, 'ab_render.html', user_info=user_info)
# 方式2:使用python内置方法locals()
return render(request, 'ab_render.html', locals())
静态文件配置
静态文件:前端已经写好的,直接调用的文件:css文件、js文件、图片文件等。
-
django中默认html文件存放在
templates
文件夹内, -
django中默认静态文件存放在
static
文件夹内, -
如果采用命令行方式创建的django项目,这两个文件夹都需要在配置文件
settings.py
中做基本的配置。
静态文件配置
在浏览器中输入url可以找到对应的资源,这是因为后端url中有对应的路由匹配视图关系;如果没有开设这个匹配关系,是找不到对应资源的。
同理,html页面需要的一些静态文件,如果我们不在urls.py
中添加匹配关系,也是找不到的。
幸运的是,为了避免此处建立匹配关系的复杂,django帮我们做了很多工作,我们只需在配置文件中,做一些简单的配置即可。
# 模版文件配置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
},
]
# 静态文件配置
STATIC_URL = '/static/' # 此处的'/static/'是令牌的名字
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'), # 此处的'static'是具体存放静态文件的文件夹的名字
os.path.join(BASE_DIR, 'static1'),
os.path.join(BASE_DIR, 'static2'),
]
模版文件login.html
中开头的static
指的是令牌的名字,而不是具体存放静态文件的文件夹名。
<head>
<link rel="stylesheet" href="static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
静态文件动态解析
如果修改了配置文件中的令牌名,那么需要手动修改模版文件中出现的所有令牌名。很显然设置是很繁琐的。
为类解决这个需求,django提供了静态文件动态解析的功能,使用此功能只需要修改配置文件的令牌名,而无需修改模版文件内的内容。
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
补充:前期使用django提交post请求的时候,需要注释配置文件中的这行代码
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',
]
request对象方法
request.method # 返回请求方式, 并且是全大写的字符串形式
request.POST # 获取用户post请求提交的普通数据,不包含文件
request.POST.get() # 只获取列表最后一个元素,字符串
request.POST.getlist() # 获取整个列表
request.GET # 获取用户提交get请求的数据
request.GET.get() # 同request.POST.get()
request.GET.getlist()
补充:get请求携带的数据有大小限制,而post请求携带的数据没有限制。
登录案例简单演示:views.py
from django.shortcuts import render, HttpResponse
def login(request):
"""
返回一个登陆界面
get请求和post请求应该有不同的处理机制
:param request: 请求相关的数据对象 里面有很多简易的方法
:return:
"""
if request.method == 'GET':
return render(request, 'login.html')
username = request.POST.get('name')
password = request.POST.getlist('password')
if username == 'xliu' and password[0] == '123456':
return HttpResponse('登录成功')
else:
return HttpResponse('登录失败')
pycharm连接MySQL数据库
pycharm可以充当很多数据库软件的客户端,连接是使用的前提是需要先创建好库。
三个位置查找连接数据库面板
- 右侧上方database
- 左下方database
- 配置里面的plugins插件搜索安装
- 再没有卸载pycharm重新装
django连接MySQL数据库
django默认自带的数据库是sqlite3,我们想要修改为mysql,需要做两件事:第一件事,配置文件修改配置;第二件事,添加代码声明。
1、修改配置
#1 注释默认用的是sqkite3
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
#2 django链接MySQL
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': db_name,
'USER': 'root',
'PASSWORD': 'admin123',
'HOST': '127.0.0.1',
'PORT': 3306,
'CHARSET':'utf8'
}
}
2、代码声明
django默认用的是mysqldb
模块链接MySQL,但是该模块的兼容性不好,需要手动改为用pymysql
链接。
手动告诉django使用pymysql
:在项目名下的__init__.py
文件或者任意的应用名下的__init__.py
文件中书写以下代码。
import pymysql
pymysql.install_as_MySQLdb()
django ORM
ORM,对象关系映射;作用
:能够让一个不用sql语句的小白也能够通过python 面向对象的代码简单快捷的操作数据库;缺点
:封装程度太高,有时候sql语句的效率偏低,需要你自己写SQL语句。
书写类
from django.db import models
class User(models.Model): # 必须继承models.Model
id = models.AutoField(primary_key=True)
# id int primary_key auto_increment
username = models.CharField(max_length=32, verbose_name='用户名')
# username varchar(32)
password = models.IntegerField()
# password int
数据库迁移命令
python3 manage.py makemigrations 将操作记录先保存起来(migrations文件夹)
python3 manage.py migrate 将操作真正的同步到数据库中
注意:只要你修改了models.py
中跟数据库相关的代码,就必须重新执行上述的两条命令,才能真正的修改数据库中的数据。
补充:
-
CharField
必须要指定max_length
参数,不指定会直接报错 -
verbose_name
该参数是所有字段都有的,用来对字段做解释说明 -
当我们自己不定义主键时,orm会自动建一个名为
id
的主键字段
字段的增删改查
# 字段的增加
#1.直接执行迁移命令,在终端内直接给出默认值
#2.该字段可以为空, null=True
#3.直接给字段设置默认值, default='study'
# 然后再执行两条迁移命令
# 字段的修改
直接修改代码然后执行数据库迁移的两条命令即可!
# 字段的删
直接注释对应的字段然后执行数据库迁移的两条命令即可!
执行完毕之后字段对应的数据也都没有了
"""
在操作models.py的时候一定要细心, 千万不要注释一些字段,
执行迁移命令之前最好先检查一下自己写的代码
"""
数据的增删改查
查数据:filter()
、all()
from app01 import models
res = models.User.objects.filter(username=username)
user_obj = res.first()
user_obj = res[0] # 等价
all_obj = models.User.objects.filter() # 方式1, 查所有数据
all_obj = models.User.objects.all() # 方式2, 查所有数据
filter
括号内可以携带多个参数,参数与参数之间默认是and关系,类似mysql的where- 返回值可以看成是列表套数据对象的格式,返回值支持索引/切片操作,但是不支持负数索引;不推荐使用索引,推荐用
first()
方法。 filter
括号内什么都不写,则返回表中所有的数据;不过这种方式语意不明确,不推荐使用。all()
方法是查询所有数据时经常使用的方法。
增加数据:create()
# 方式1:create()
res = models.User.objects.create(username=username, password=password)
# 方式2,实例化对象
user_obj = models.User(username=username, password=password)
user_obj.save() # 保存数据
- 使用
objects
对象的create
方法直接保存数据,且直接返回当前对象 - 方式2采用类的实例化方法实例化一个对象,然后调用对象的默认
save
方法保存数据
修改数据:update()
# 修改数据方式1
models.User.objects.filter(id=edit_id).update(username=username,password=password)
# 修改数据方式2
edit_obj = models.User.objects.filter(id=edit_id).first()
edit_obj.username = username
edit_obj.password = password
edit_obj.save()
- 修改数据的方式有两种:
update()
方法、对象属性修改后save()
保存。 update()
方法属于批量操作方式,且速度较快,推荐使用。- 对象属性修改后
save()
保存的方式,针对具体某一个数据的修改,速度较慢(对象的每个属性都挨个重新赋值一次),一般不推荐使用。
修改数据操作时的逻辑:模版文件中提前将每个修改按钮上
a
标签的action
属性绑定好数据的id
;当点击修改按钮时,a
标签通过get请求的方式,将修改数据的id
交给后台视图函数;最后视图函数拿着这个id
做修改逻辑处理。
删除数据:delete()
models.User.objects.filter(id=delete_id).delete()
- 注意:删除前需要二次确认
- 删除数据内部其实并不是真正的删除,我们会给数据添加一个标识字段用来表示当前数据是否被删除了,如果数据被删了仅仅只是讲字段修改一个状态
orm中创建表关系
表关系:一对多、多对多、一对一
一对多: models.ForeignKey()
# 图书表与出版社表
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2)
publish = models.ForeignKey(to='Publish') # 一对多,外键关联
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
- 一对多时,外键放在多的一方;
- 创建外键时使用
ForeignKey
,需要指定关联的表名字,默认被关联的字段是被关联表的主键字段。 publish
做外键字段,但内部ORM会自动将publish
转变为publish_id
,因此我们在书写该字段时无需再手动加_id
- 外键关联时,django1版本都是默认级联删除和级联更新的。
多对多:models.ManyToManyField()
# 图书表与作者表
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish = models.ForeignKey(to='Publish') # 一对多,外键关联
authors = models.ManyToManyField(to='Author') # 多对多,
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
- 多对多关系时,外键字段建在任意一方均可,但推荐放在查询频率较高的一方;
authors
是一个虚拟字段,主要是用来告诉ORM,书籍表和作者表是多对多关系;- ORM会自动创建第三张关系表,第三张表
app01_book_author
,三个字段分别为:id
、book_id
、author_id
一对一:models.OneToOneField()
# 作者表和作者详情表
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail') # 一对一,
class AuthorDetail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=32)
- 一对一的关系时,外键字段建在任意一方都可以,但推荐放在查询频率较高的一方;
- 默认也是直接关联被关联表的主键字段,即
AuthorDetail
表的主键id
字段; OneToOneField
也会自动给字段加_id
后缀,默认也是级联删除和级联更新的。
django请求生命周期流程图
补充:
- 缓存数据库一般可以放静态页面的数据,通过
nginx
分发过去,减少后台服务器的压力。 - WSGI网关协议的作用是将请求解析数据解析封装,将响应数据打包分发。
- django使用的UWGI协议是
wsgiref
模块,但是其并发量小(1000~)稳定性差,线上部署一般使用uwsgi
模块。