大家好,欢迎来到IT知识分享网。
1 MVC与MTV模型
1.1 MVC
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
1.2 MTV
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
- M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
- T 代表模板 (Template):负责如何把页面展示给用户(html)。
- V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求会去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
2 Django的下载与基本命令
2.1 下载Django
方式一:在命令行输入:pip3 install djangopip3 install django==1.11.9 -i http://pypi.hustunique.org/simple 指定版本号,指定国内镜像方式二:用pycharm安装方式三:用pycharm的Terminal的命令行安装# 验证是否下载成功cmd窗口直接输入django-admin有一长串结果展示表明成功(需提前配置解释器环境变量)
2.2 创建一个django project
cd到项目想要存放的路径下
django-admin.py startproject mysite(项目名)
当前目录下会生成mysite的工程,目录结构如下:
- manage.py —– Django项目里面的工具,通过它可以调用django shell和数据库等。
- settings.py — 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
- urls.py —– 负责把URL模式映射到应用程序。
2.3 在mysite目录下创建应用
python3 manage.py startapp blog(应用名)
2.4 启动django项目
cd到项目所在目录下
python3 manage.py runserver IP:PORT # IP:PORT可以不写 默认在本地8000端口起服务
2.5 pycharm创建django项目
1.创建django项目
file-->new project-->选 django 即可,不用修改配置
2.启动django项目
方式一:terminal窗口输入命令启动
方式二:pycharm上方运行键启动
3.创建应用
方式一:terminal窗口输入命令启动
方式二:pycharm上方Tools-->Run manag.py Task-->窗口输入 startapp 应用名
3 主要文件介绍
-mysite项目文件夹
-mysite同名文件夹
-settings.py 项目配置文件
-urls.py 总路由层
-wsgi.py wsgiref模块
-manage.py 项目入口文件
-db.sqlite3 运行项目后自动创建(django自带的小型数据库)
-templates 专门用来存放html文件,手动创建
-static 存储html页面所需静态资源
-应用文件夹 通过命令创建(可以创建任意个数)
--migrations 存储数据迁移记录
--admin.py django提供的后台管理
--apps.py 用于配置文件的应用注册(创建的应用都需要去配置文件中注册)
--models.py 模型层(与数据库相关)
--views.py 视图层(编写当前应用核心业务逻辑代码)
--tests.py 自带的测试文件
4 注意事项
1、计算机名称不要出现中文
2、python解释器尽量用3.4-3.6版本
3、项目中所有的文件名称不要出现中文
4、多个项目文件尽量不要嵌套,做到一项一夹,一个pycharm窗口只开一个项目
5、如果项目报错,点击最后一个错误信息,去源码中把itmes后的逗号删除掉
5 重要知识点
5.1 命令行与pycharm创建项目的区别
pycharm创建django项目,会自动帮你创建templates文件夹,并且还会自动在settings.py中配置好路径,之后在找templates中的html文件时不用再拼接路径;如果用命令行创建django项目时,不但要单独创建templates文件夹,还要到settings.py中去配置路径:
5.2 创建的应用一定要去配置文件中注册
也可以简写为’app01′
6 Django小白必会三板斧
HttpResponse 返回字符串类型的数据
return HttpResponse('hello i am djanggo')
render 返回html文件,即返回html渲染的页面
return render(request, 'mydjangohtml.html')
# 第一个参数request,第二个参数是html文件名,配置路径后,会自动帮你查找文件名
后端利用 render
给页面传值的两种方式
方式一:指名道姓直接传值
return render(request, 'render_html.html',{'data': user_dict})
# 更精准,节省资源
# 第三个参数,传入一个字典,可以传多个值{'data': user_dict,'data2':123}
# html文件用模板语法接收,{{data}}
方式二:locals()将所在名称空间所有的名字全部传递给html页面
return render(request, 'render_html.html',locals())
# 当要传的数据特别多的时候更方便
# html文件会接收到locals传来的所有变量名,{{user_dict}}、{{request}}
redirect 重定向
redirect括号内可以直接写url,也可以直接写别名;但redirect只能反向解析不带参数的,如果别名需要额外传参,就必须使用reverse
1 return redirect('http://taobao.com/') # 跳转到其他url
2 return redirect('/home/')
# 跳转到自己的url,自己定义的路由/home,以及home函数
# 跳转自己的url,不用加ip和端口,只需要后缀
7 基于Django实现的一个简单示例
7.1 URL控制器
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/',views.index),
]
7.2 视图
from django.shortcuts import render
def index(request):
import datetime
now=datetime.datetime.now()
ctime=now.strftime("%Y-%m-%d %X")
return render(request,"index.html",{"ctime":ctime})
7.3 模版
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>当前时间:{{ ctime }}</h4>
</body>
</html>
8 Django静态文件配置
静态文件是前端已经写好了的,能够直接调用使用的文件。我们将html文件默认都放在templates文件夹下,将网站所使用的静态文件默认都放在static文件夹下。django默认是不会自动帮你创建static文件夹 需要你自己手动创建:
-static
-js文件夹 存放网站自己写好的js文件
-css文件夹 存放网站自己写好的css文件
-img文件夹 存放网站用到的图片文件
-第三方前端文件 如bootstrap-3.4.1-dist、font-awesome-4.7.0、bootstrap-sweetalert-master、jQuery-3.6.0.js
在浏览器中输入url能够看到对应的资源,是因为后端提前开设了该资源的借口,如果访问不到资源,说明后端没有开设该资源的接口。
<script src="../static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
按此路径导入,获取不到bootstrap文件的资源,相当于浏览器访问这个资源http://127.0.0.1:8000/static/bootstrap-3.4.1-dist/js/bootstrap.min.js
因为后端没有开放静态文件的资源接口,因此访问不到,需要到urls.py中去开接口
静态文件配置,settings.py
STATIC_URL = '/static/' # 访问静态文件的令牌
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'), # 拼接static文件夹路径,可以访问到static文件夹下所有文件
#os.path.join(BASE_DIR,'static1'),
#os.path.join(BASE_DIR,'static2'),
]
<script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
配置好后按此路径导入静态文件,这里的/static相当于访问静态文件的令牌,如果你想要访问静态文件,必须以static开头
一旦令牌对了,就到STATICFILES_DIRS列表的文件夹中,从上往下依次查找/bootstrap-3.4.1-dist/js/bootstrap.min.js这个文件路径,都没有才报错
配置好的静态文件令牌如果被修改,那么所有的导入静态文件的位置都要进行修改,利用模板语法导入静态文件可以动态解析,即使令牌修改,也能动态解析获取到静态文件资源。
{% load static %} 先导入模块
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
9
1、不写:默认朝当前页面所在的url提交数据
如访问/login/,第一次get请求访问返回登录页面,第二次form表单submit提交数据时访问,会访问两次login接口
2、全写:指名道姓的向某个url提交数据
3、只写后缀:如/index/,会自动补全当前这个后缀的ip和端口,朝/index/这个url提交数据
form表单默认是get请求提交数据,数据放在url ?后面
http://127.0.0.1:8000/login/?username=jason&password=123
通过method=”post” 参数设置,控制请求提交的方式。
9.2 request对象
如果form表单action参数不写,那么访问/login,然后提交数据,发生两次请求,一次get,一次post,触发的都是login函数执行;get请求只需获取一个页面,post请求需要获取用户提交的数据,两者的处理机制是不同的,在login函数中,如何去判断请求是get还是post?
于是引出了request对象方法:
request.method # 返回请求方式 并且是全大写的字符串形式 <class 'str'>
if request.method == 'POST' # 通过判断当前请求方式,执行对应的业务逻辑
request.POST # 获取用户post请求提交的普通数据不包含文件
<QueryDict: {'username': ['zell'], 'password': ['2222'], 'hobby': ['111', '222', '333']}> # 拿到一个字典,字典的key取决于html页面的name属性
request.POST.get() # 根据key取值,只获取列表最后一个元素
request.POST.getlist() # 如果要获取列表里全部元素,要用getlist获取列表
request.GET # 获取用户get请求提交的数据,即url?后的数据
request.GET.get() # 只获取列表最后一个元素
request.GET.getlist() # 直接将列表取出
# get请求携带的数据是有大小限制的,而post请求则没有限制
10
MySQL
1 点开Database-> +号 -> Data Soures支持的数据库软件-> 选择MySQL
2 Download 下载安装驱动
3 填写host、port、user、password、Database(指定要操作的库)-->点击测试,如果失败更换驱动
4 操作表:增删改查数据,注意submit绿色小点同步提交到服务器
11 Django链接MySQL
Django默认用的是sqlite3数据库,如果替换为MySQL。
第一步:settings.py中修改配置
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db_bbs',
'USER': 'root',
'PASSWORD': 'admin123',
'HOST': '127.0.0.1',
'PORT': 3306,
'CHARSET': 'utf8',
}
}
第二步:代码声明
Django默认用的是mysqldb模块链接MySQL,但是该模块的兼容性不好,需要手动改为用pymysql链接。需要告诉Django不要用默认的mysqldb,而是用pymysql。在项目文件夹或应用文件夹下的_ _init_ _.py文件中书写如下代码:
import pymysql
pymysql.install_as_MySQLdb()
# 报错原因
#1 django版本和pymysql版本不兼容
#2 编码问题,报错源码decode改为encode
12 初识Django ORM
ORM:对象关系映射,能够让一个不会sql语句的小白,也能够通过python面向对象的代码,简单快捷的操作数据库。不足:封装程度过高,有时候sql语句的效率偏低,需要自己写sql语句。
pymysql | ORM | MySQL |
类 | 映射 | 表 |
对象 | 映射 | 记录 |
对象.属性 | 映射 | 操作记录(记录某个字段对应的值) |
注意:ORM只能在表层面创建操作,不会帮你创建库,需要自己创建好。
12.1 ORM基础操作
models.py中,写一个类(创建表):
class User(models.Model):
# id int primary_key auto_increment 设置主键
id = models.AutoField(primary_key=True)
# username varchar(32)
username = models.CharField(max_length=32, verbose_name='用户名')
# password int
password = models.IntegerField()
# 创建类,必须继承父类models.Model
# 用模型建表,如果主键名字用id,可以不自己建,ORM会自动创建,仅限"id"
# CharField类型必须指定宽度,即max_length参数
# verbose_name参数建议加上,用来给字段做备注
数据库迁移命令,创建了类还要告诉ORM,将你的操作映射到数据库去。
python3 manage.py makemigrations # 将操作记录记录到小本本上(migrations文件夹)
python3 manage.py migrate # 将操作真正的同步到数据库中
只要你修改了models.py中跟数据库相关的代码 就必须重新执行上述的两条命令。
12.2 ORM的使用
字段的增删改,models.py
# 字段的增加
# 当表中已经有数据,新增的字段不能是空字段
1.可以在终端内直接给出默认值
age = models.IntegerField() 在终端输入makemigrations,按照提示选1,给一个默认值,如:18 -->migrate提交数据
2.定义时就表明该字段可以为空
info = models.CharField(max_length=32,verbose_name='个人简介',null=True)
3.定义时就给该字段设置一个默认值
hobby = models.CharField(max_length=32,verbose_name='兴趣爱好',default='study')
# 字段的修改
可以修改字段名、字段属性(类型)
直接修改代码然后执行数据库迁移的两条命令即可!
# 字段的删除
直接注释对应的字段然后执行数据库迁移的两条命令即可!
执行完毕之后字段对应的数据也都没有了,再打开注释也没有,只有数据库层面可以恢复
"""
在操作models.py的时候一定要细心
千万不要注释一些字段
执行迁移命令之前最好先检查一下自己写的代码
"""
数据的增删改查
# 查
原生sql:select * from user where username='用户输入的username'
res = models.User.objects.filter(username=username)
"""
返回值是一个queryset对象, 列表套数据对象,[数据对象1,数据对象2...]
它也支持索引取值 切片操作 但是不支持负数索引
filter括号内可以携带多个参数,参数与参数默认是and关系,filter筛选,跟where作用差不多
不推荐你使用索引的方式取值,而是用对象自带的方法first()
user_obj = models.User.objects.filter(username=username).first() 拿到列表里的第一个元素
"""
查看所有数据:
models.User.objects.filter() # filter不加任何条件即拿到所有数据对象的列表,但语义不明确
models.User.objects.all() # 返回值是一个queryset对象,一个列表,如果传给html展示,需要用到模板语法,for循环
# 增
原生sql: insert into user(username, password) values('用户输入的username', ‘用户输入的password’)
res = models.User.objects.create(username=username,password=password) # 返回值就是当前被创建的对象本身
# 第二种增加 直接调用类实例化产生一个数据对象,没涉及到ORM
user_obj = models.User(username=username,password=password)
user_obj.save() # 保存数据
# 改
方式一: models.User.objects.filter(id=edit_id).update(username=username, password=password)
# 将filter查询出来的列表中所有对象全部更新,因为filter拿到的是一个列表,可能有多个对象,它是批量更新
# 只更新被修改的字段
方式二:
edit_obj = models.User.objects.filter(id=edit_id).first() # 先拿到即将要被编辑的那条数据对象
edit_obj.username = username
edit_obj.password= password
edit_obj.save()
# 用对象点属性进行赋值操作,然后保存
# 这种更新是指名道姓的单独更新,会从头到尾将数据的所有字段全部更新一遍,无论字段是否被修改,字段多了效率会非常低
# 删
models.User.objects.filter(id=delete_id).delete() # filter筛选出对应的数据,直接删除
补充:
# 真正的删除功能应该需要二次确认
# 删除数据内部其实并不是真正的删除 我们会给数据添加一个标识字段用来表示当前数据是否被删除了,如果数据被删了仅仅只是将字段修改一个状态
12.3 ORM中创建表关系
先将基表创建出来,然后再添加外键字段;依次创建即可,不像MySQL要先创建被关联表;django1.x版本默认级联操作,其他版本要手动设置
一对多关系
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish = models.ForeignKey(to='Publish') # to_field默认不写,就是关联出版社的主键字段
# 如果外键字段对应是ForeignKey,ORM在创建表时会自动在字段后面加_id,如publish_id,一对一表关系也会自动给外键字段加_id,因此不要手动去加
多对多关系
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') # authors是一个虚拟字段,用来告诉ORM图书与作者是多对多关系,让ORM自动帮你创建第三方关系表
一对一关系
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail') # author_detail外键字段建在任意一方均可,推荐建在查询频率较高的一方
13 Django 请求生命周期流程
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/32698.html