Django简介

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 django
pip3 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 request对象方法初识

9.1 form表单浅析

form表单action参数

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 pycharm连接MySQL

pycharm可以充当MySQL的客户端,类似于Navicat,三个位置查找数据库相关:右侧上方Database、左下角Database、配置中插件plugins搜索安装

使用方式:

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 请求生命周期流程

posted @ 2022-12-23 21:18  不会钓鱼的猫  阅读(312)  评论(0编辑  收藏  举报