推荐教程:https://code.ziqiangxuetang.com/django/django-tutorial.html
MVC设计模式(Model,View,Controller)
1 Model:用于封装与应用程序的业务逻辑相关的数据及对数据的处理方法,是Web应用程序中用于处理应用程序的数据逻辑部分,Model通常只提供功能性的接口,通过这些接口可以获取Model的所有功能。 2 3 View:负责数据的显示和呈现,View是对用户的直接输出。 4 5 Controller:负责从用户端收集用户的输入,可以看成提供View的反向功能,主要处理用户交互。 6
Django是MVT模式,本质上还是MVC模式
1 MVT本质上与MVC没什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同。 2 3 Model:负责业务对象与数据库(ORM)的对象 4 5 View:负责业务逻辑,并在适当的时候调用Model和Template 6 7 Template:负责把页面展示给用户 8 9 注意:Django中还有一个url分发器(也可以叫做路由),主要用来将一个个URL页面的请求分发给不同的View进行处理,View再调用相应的Model和Template。 10
1.虚拟环境的安装
作用:隔离项目运行环境
安装virtualenvwrapper,详情见环境搭建之virtualenv的安装
2.配置Django项目开发环境
创建项目虚拟环境: (删除:rmvirtualenv 虚拟环境名称)
mkvirtualenv --python=/usr/local/python3.5.3/bin/python venv_name
其中,--python=的是你要使用的python解释器的路径,后面的是虚拟环境的名字
进入虚拟环境: (退出:deactivate)
workon 虚拟环境名称
指定python解释器—>用绝对路径,在编译器中编辑时要指定编辑器的解释器。
安装XXX依赖包:pip install XXX
pip freeze: 查看虚拟环境新安装的包
pip install django==2.2 (== 用来指定需要安装的版本)
3.Django项目
创建项目:django-admin startproject axf
Django 目录介绍
1 manage.py: 2 是Django用于管理本项目的命令行工具,之后进行站点运行,数据库自动生成等都是通过本文件完成。 3 4 axf/__init__.py: 5 告诉python该目录是一个python包,暂无内容,后期一些工具的初始化可能会用到 6 7 axf/settings.py: 8 Django项目的配置文件,默认状态其中定义了本项目引用的组件,项目名,数据库,静态资源等。 9 10 axf/urls.py: 11 维护项目的URL路由映射,即定义当客户端访问时由哪个模块进行响应。 12 13 axf/wsgi.py: 14 定义WSGI的接口信息,主要用于服务器集成,通常本文件生成后无需改动。
启动服务:python manager.py runserver [ip:port] 默认本机8000端口
生成迁移:python manager.py makemigrations
执行迁移:python mananger.py migrate
settings中的DataBase模块,可以直接连接操作数据库Sqlite和MySQL
1 2 1 'ENGINE':'django.db.backends.mysql', # 驱动 3 2 'NAME':'school', # 数据库名 4 3 'USER':'root', # 用户名 5 4 'PASSWORD':'123', # 用户密码 6 5 'HOST':'127.0.0.1', # 主机 7 6 'PORT':'3306', # 端口 8 7
安装sql驱动:pip install pymysql
安装后还需要在__init__.py中添加初始化代码
import pymysql
pymysql.install_as_MySQLdb() # 导入驱动
创建应用:python manager.py startapp XXX(应用名)
将应用添加到settings.py.INSTALLED_APPS中使应用生效
应用目录介绍:
1 __init__.py: 2 其中暂无内容,使得app成为一个包 3 4 admin.py: 5 管理站点模型的声明文件,默认为空 6 7 apps.py: 8 应用信息定义文件,在其中生成了AppConfig,该类用于定义应用名等数据 9 10 models.py: 11 添加模型层数据类文件 12 13 views.py: 14 定义URL相应函数(路由规则) 15 16 migrations包: 17 自动生成,生辰迁移文件的 18 19 tests.py: 20 测试代码文件
创建响应函数连接应用路由到项目路由:
1 首先我们在views.py中建立一个路由响应函数 2 from django.http import HttpResponse 3 4 def welcome(request): 5 return HttpResponse('HelloDjango'); 6 7 接着我们在urls中进行注册 8 from App import views 9 path('welcome/',views.welcome) 10 11 基于模块化的设计,我们通常会在每个app中定义自己的urls 12 13 在项目的urls中将app的urls包含进来 14 from django.conf.urls import include 15 path('welcome/',include('App.urls')) 16
模板文件templates:
客户端显示的实际上是经过处理的模板HTML
1 模板文件实际上就是我们用HTML写好的页面 2 3 在项目文件夹下创建模板文件夹templates 4 在工程目录的需要注册 5 settings中的TEMPLATES中的DIRS中添加 6 os.path.join(BASE_DIR,'templates') 7 在模板文件夹中创建模板文件 XXX.html 8 9 在views中去加载渲染模板 10 1.from django.template import loader 11 template = loader.get_template('xxx') 12 return HttpResponse(template.render()) 13 14 2 return render(request,'xxx') #我喜欢这种
模型介绍model:
以学生班级为例,定义两个模型结构
1 from django.db import models 2 # 定义年级 3 class Grade(models.Model): 4 g_name = models.CharField(max_length=10) 5 g_date = models.DateTimeField() 6 g_girlnum = models.IntegerField() 7 g_boynum = models.IntegerField() 8 isDelete = models.BooleanField() 9 10 # 定义学生 11 class Students(models.Model): 12 s_name = models.CharField(max_length=20) 13 s_gender = models.BooleanField(default=True) 14 s_age = models.IntegerField() 15 s_info = models.CharField(max_length=20) 16 isDelete = models.BooleanField(default=False) 17 # 关联外键>>理解原理需要学习数据库 18 s_grade = models.ForeignKey(Grade)
上面在settings中设置了MySQL的连接参数,这里就可以迁移数据到MySQL数据库
生成迁移文件:python manager.py makemigrations
执行迁移操作:python mananger.py migrate
测试数据模型:
1 插入数据: 2 { 3 # 实例化对象: 4 对象=类名; grade_one = Grade() 5 # 对象属性赋值: 6 对象.属性=值;grade_one.g_girlnum = 55 7 ......... 8 对象.save() 9 } 10 11 查询: 12 查询所有数据:类名.objects.all();Grade.objects.all() 13 根据id查询一条数据:Grade.objects.get(pk=id) 14 根据条件筛选:Grade.objects.filter(条件) 15 16 修改数据: 17 { 18 # 查询要修改的对象: 19 对象=类名.objects.查询方法; 20 grade_one = Grade.objects.get(pk=id) 21 22 # 对象属性赋值: 23 对象.属性=值;grade_one.g_girlnum = 55 24 ......... 25 对象.save() 26 } 27 28 删除数据: 29 { 30 # 查询要删除的对象: 31 对象=类名.objects.查询方法; 32 grade_one = Grade.objects.get(pk=id) 33 34 对象.delete() 35 grade_one.delete() 36 }
1 在App.views中 2 3 # 导入包: 4 from App.models import * 5 from django.utils import timezone 6 from datetime import * 7 8 # 创建插入班级数据的函数: 9 def add_grade(request): 10 grade_one = Grade() 11 grade_one.g_name = 'python9102' 12 grade_one.g_date = datetime(year=9102, month=7, day=28) 13 grade_one.g_girlnum = 55 14 grade_one.g_boynum = 6 15 grade_one.save() 16 return HttpResponse('add OK') 17 18
创建学生数据:
1 在views中创建插入学生数据的函数: 2 3 def add_student(request): 4 stu = Students() 5 stu.s_name = 'rook' 6 stu.s_age = 18 7 stu.s_gender = True 8 stu.s_info = '学渣2' 9 stu.s_grade = Grade.objects.get(pk=2) 10 stu.save() 11 return HttpResponse('add {} OK'.format(stu.s_name))
Django中获得关联对象集合:
获取班级中的所有学生
对象名.关联的类名小写_set.all()
grade_one.student_set.all()
---------------------------------------------------------------------------
数据从数据库到客户端的常用流程:
客户端访问→路由urls↓
urls根据规则调取views中对应方法↓
views中的方法从models中取得数据↓
views将数据渲染进templates中的对应的模型↓
将渲染好的模板返回给客户端。。。点击查看模型图
Django模板语法:
1 views中传参: 2 def 函数名(request): 3 4 XXX。。。处理逻辑。。。 5 6 data = { 7 key:value, 8 。。。。。。 9 } 10 return render(request, '模板相对templates的路径', context=data) 11 12 模板语法: 13 直接取值用{{ key }}接受views函数中传过来的context的值 14 表达式:{% for XX in key %}。。。等多种表达式 15 处理逻辑。。。 16 {% endfor %} 17 18 反向解析语法:{ % url 'name' 'p1' 'p2' %}?= 19 ’get请求方式‘,'p1'和 'p2'是数据
1 将接收到的数据当成普通字符串处理还是当成HTML代码来渲染 2 渲染成html: 3 {{ code|safe}} 4 5 {% autoescape off%} 6 code 7 {% endautoescape %} 8 9 不想渲染 10 {% autoescape on%} 11 code 12 {% endautoescape %}
1 某些恶意网站包含链接,表单,按钮,Js利用登陆用户在浏览器中的认证信息,进行非法操作,攻击服务,破坏数据 2 3 在表单中添加 4 {% csrf_token %} 5 6 在settings中的中间件MIDDLEWARE中配置打开 7 'django.middleware.csrf.CsrfViewMiddleware', 8
1 extends 继承,写在开头位置 2 {% extends '父模板路径' %} 3 4 关键字block: 5 {% block XXX%} 6 code 7 {% endblock %} 8 9 include:加载模板进行渲染 10 格式{% include '模板文件' %} 11
参考文档:菜鸟教程||博客园-郭楷丰 详细图文随笔||CSDN参考博客
Django模型:
Django的model应用的是ORM模式
ORM
全拼Object-Relation Mapping(对象关系映射);
1 定义表信息: 2 class Meta: 3 db_table = xxx 定义数据表名,推荐使用小写字母 4 ordering =[] 5 升序ordering['id'],降序ordering['-id'] 6 7 过滤条件: 8 all():返回所有数据 9 filter():返回符合条件的数据 10 exclude():过滤掉符合条件的数据 11 order_by():排序 12 values():一条数据就是一个字典,返回一个列表 13 get():返回一个满足条件的对象,没有或多个会抛异常 14 first():返回查询集中的第一个对象 15 last():返回查询集中的最后一个对象 16 count():返回当前查询集中的对象个数 17 exists():判断查询集中是否有数据,有返回True 18 可以连用 19 20 在模型类中增加类方法去创建对象: 21 @classmethoddef 22 create(cls,name,age): 23 自定义创建对象的方法。。。 24 25 比较运算: 26 语法:属性名称__比较运算符=值 27 外键:属性名_id 28 Student.objects.all()[0:5];取前5个,下标不能是负数 29 filter(sname__contains='%');sname中包含%,开头加i不区分大小写 30 startswith,endswith:以values开头或结尾,开头加i不区分大小写 31 isnull,isnotnull:是否为空(sname__isnull=False) 32 filter(pk__in=[2,4,6,8]);是否包含在范围内 33 gt,gte,lt,lte:大于,大于等于,小于小于等于 34 35 处理时间序列: 36 filter(lasttime__year=2017) 37 filter(pub_date__gt=date(1990,1,1));导入datetime.date 38 39 跨关系查询: 40 模型类名__属性名__比较运算符,实际上就是处理的数据库中的join 41 grade = Grade.objects.filter(student__scontend__contains='楚人美') 42 描述中带有'楚人美'这三个字的数据属于哪个班级 43 44 聚合函数: 45 使用aggregate()函数返回聚合函数的值 46 Avg:平均值 47 Count:数量 48 Max:最大 49 Min:最小 50 Sum:求和 51 Student.objects().aggregate(Max('sage')) 52 53 F对象: 54 可以使用模型的A属性与B属性进行比较 55 grades = Grade.objects.filter(ggirlnum__gt=F('gboynum') ) 56 F对象支持算数运算 57 grades = Grade.objects.filter(ggirlnum__gt=F('gboynum') +10 ) 58 59 Q对象: 60 过滤器的方法中的关键参数,常用于组合条件 61 年龄小于25 62 Student.objects.filter(Q(sage__lt=25)) 63 Q对象语法支持 | (or), & (and), ~(取反) 64 年龄大于等25 65 Student.objects.filter(~Q(sage__lt=25)) 66 filter(Q(readcount__gt=20) | Q(id__lt=3))
1 Django模型对应关系有: 2 1:1(一对一) 3 1:N(一对多) 4 M:N(多对多) 5 常见的几种数据关系,django都提供了很好的支持 6 7 1 : 1 8 使用models.OneToOneField()进行关联 9 class Card(models.Model): 10 person = models.OneToOneField(Person,on_delete='CASCADE') 11 12 绑定卡与人的一对一关系 13 默认情况下,当人被删除的情况下,与人绑定的卡就也删除了 14 可以使用on_delete进行调整 15 on_delete: 16 models.CASCADE:默认值 17 models.PROTECT:保护模式 18 models.SET_NULL:置空模式 19 models.SET_DEFAULT:置默认值 20 models.SET();删除的时候重新动态指向一个实体 21 访问对应元素:person.pcard 22 23 1 : N 24 使用models.ForeignKey关联 25 删除时同 1 : 1 26 获取对应元素 grade.student_set 27 28 M : N 29 使用models. 30 删除会删除指定对象和关系表中的关系映射 31 获取对应元素Goods和Buyer 32 goods. buyer_set 33 buyer. bgoods 34 买家添加buyer.bgoods.add 35 买家清空buyer.bgoods.clear 36 买家移除buyer.bgoods.remove 37 38 模型继承: 39 在models中添加Meta,指定是否抽象,然后进行继承 40 class Animal(models.Model): 41 xxx 42 class Meta: 43 abstract = True/False 44 45 class Dog(Animal): 46 xxx
模型关系参考:https://blog.csdn.net/duus_nabolun/article/details/83107276
Django数据查询时返回的是QuerySet对象;参考:Django ORM之QuerySet
自定义管理器参考:django之ORM介绍与基本使用↓↓
参考文档:菜鸟教程||django之ORM介绍与基本用法||django之ORM查询操作
Django-views:
Django中views模块是控制中心,几乎多有逻辑代码都在这个模块编写
HTTP请求中的两个核心对象:
HttpRequest:请求对象
HttpResponse:返回对象
Django在接收到http的请求后,会将请求生成一个WSGIRequest对象,并且作为参数传递给views函数的(request)参数,这个对象上包含着客户端上传的各种信息
视图函数处理完相关的逻辑后,也需要返回一个HttpResponseBase对象或者他的子类对象给浏览器。用的最多的子类对象是HttpResponse
WSGIResquest对象常用的属性和方法:(request)
1 常用属性: 2 path:请求的完整路径,不包含域名和参数 3 method:请求的HTTP方法(GET或POST) 4 GET:GET参数的类字典对象 5 POST:POST参数的类字典对象 6 FILES:上传文件的信息 7 COOKIES:字典对象,key和value都是字符串 8 session:字典对象,key和value都是字符串 9 META:所有客户端发来的header信息 10 11 常用方法: 12 is_secure();是否采用Https协议 13 is_ajax();是否采用ajax 14 get_host;服务器的域名,+[端口号] 15 get_full_path;返回完整的path,包括参数 16 get_raw_url();获取完整url,(http://127.0.0.1:8000/index/) 17 18 QueryDict对象:(类字典对象) 19 get();获取指定key的值,没有则返回None 20 getlist();key有多个值时使用,返回一个列表
HttpResponse对象常用的属性和方法:
1 content:返回的内容 2 status_code:返回的http状态码 3 write();写入数据到content中 4 set_cookie:设置cookie 5 delete-cookie:删除cookie 6 content_type:返回数据的MIME类型默认text/html 7 浏览器器会根据这个来显示数据常用的有: 8 text/html:(默认的,HTML文件) 9 text/plain:(纯文本) 10 text/css:(css文件) 11 text/javascript:(js文件) 12 multipart/form-data:(文件提交) 13 application/json:(json传输) 14 application/xml:(xml文件)
参考文档:https://www.cnblogs.com/dxnui119/p/10434274.html
Django中cookie的使用:
1 # 设置cookie,从服务器返回的response中设置 2 response = redirect(path);重定向到某个指定的路径下 3 response.set_cookie(key,value,max_age=0) 4 # 直接设置cookie的值和value 5 # max_age是过期时间,0是默认,None是永久,接上数字是具体时间,用s做单位 6 #如:response.set_cookie('name',person.name,max_age=3600) 7 8 # 获取cookie,从客户端请求中获得 9 name = request.COOKIE.get('name') 10 response = render(request,'home.index',contex=({'name':name}) 11 return response 12 13 # 清除cookie,从response清除 14 response = redirect('namespace:name') 15 response.delete_cookie('name')
Django中session的使用:
1 # 设置session 2 #在setting中注册 3 # INSTALLED_APPS: 4 'django.contrib.sessions' 5 # MIDDLEWARE: 6 'django.contrib.sessions.middleware.SessionMiddleware' 7 #默认是加上的,在request中设置session 8 request.session['name'] = person.name 9 request.session.set_expiry(60) # 设置过期时间,单位是s 10 11 # 获取session,也是从request中获取 12 name = request.session.get('name') 13 14 # 删除session,在response中删除 15 response.delete_cookie('sessionid') # 在客户端删除session 16 del request.session['name'] # 在服务器端删除session 17 request.session.flush() # 直接清除两端的session
Django中token的使用:
1 # 设置token,首先需要建立有关token字段的表格,在response中设置 2 person.token = create_token() # create_token 是创造token的函数 3 response.set_cookie('token',person.token) 4 5 # 获取token,在request中获取token 6 person.token = request.COOKIE.get('token') 7 8 # 清除token,在response中清除 9 response.delete_cookie('token') 10 11 进行md5加密 12 import hashlib 13 def create_hash(password) 14 md5 = hashlib.md5() 15 md5.update(password.encode('utf-8')) 16 return md5.hexdigest() 17 18 uuid创建token 19 import uuid 20 token = str(uuid.uuid5(uuid.uuid4() ,'token'))
urls:
带参数的url:可以指定参数类型
版本2.:path('marke/<int:typeid>/<childcid>/', views.market, name='market),
版本1.:url(r'^news/(?P<year>d{4})/(?P<month>d+)$',views.getNews)
验证码:
一般使用第三方包:Pillow
1 安装:pip install Pillow 2 核心:Image,ImageDraw,ImageFont 3 4 绘制流程: 5 import random 6 from PIL import Image, ImageDraw, ImageFont, ImageFilter 7 8 _letter_cases = "abcdefghjkmnpqrstuwxy" # 小写字母,去除可能干扰的i,l,o,v,z 9 _upper_cases = _letter_cases.upper() # 大写字母 10 _numbers = ''.join(map(str, range(3, 10))) # 数字 11 init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) 12 13 def create_validate_code(size=(120, 30), 14 chars=init_chars, 15 img_type="GIF", 16 mode="RGB", 17 bg_color=(255, 255, 255), 18 fg_color=(0, 0, 255), 19 font_size=18, 20 font_type="Monaco.ttf", # 字体路径 21 length=4, # 验证码长度 22 draw_lines=True, 23 n_line=(1, 2), 24 draw_points=True, 25 point_chance = 2): 26 ''' 27 @todo: 生成验证码图片 28 @param size: 图片的大小,格式(宽,高),默认为(120, 30) 29 @param chars: 允许的字符集合,格式字符串 30 @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,PNG 31 @param mode: 图片模式,默认为RGB 32 @param bg_color: 背景颜色,默认为白色 33 @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF 34 @param font_size: 验证码字体大小 35 @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf 36 @param length: 验证码字符个数 37 @param draw_lines: 是否划干扰线 38 @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效 39 @param draw_points: 是否画干扰点 40 @param point_chance: 干扰点出现的概率,大小范围[0, 100] 41 @return: [0]: PIL Image实例 42 @return: [1]: 验证码图片中的字符串 43 ''' 44 45 width, height = size # 宽, 高 46 img = Image.new(mode, size, bg_color) # 创建图形 47 draw = ImageDraw.Draw(img) # 创建画笔 48 49 def get_chars(): 50 '''生成给定长度的字符串,返回列表格式''' 51 return random.sample(chars, length) 52 53 def create_lines(): 54 '''绘制干扰线''' 55 line_num = random.randint(*n_line) # 干扰线条数 56 57 for i in range(line_num): 58 # 起始点 59 begin = (random.randint(0, size[0]), random.randint(0, size[1])) 60 #结束点 61 end = (random.randint(0, size[0]), random.randint(0, size[1])) 62 draw.line([begin, end], fill=(0, 0, 0)) 63 64 def create_points(): 65 '''绘制干扰点''' 66 chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100] 67 68 for w in range(width): 69 for h in range(height): 70 tmp = random.randint(0, 100) 71 if tmp > 100 - chance: 72 draw.point((w, h), fill=(0, 0, 0)) 73 74 def create_strs(): 75 '''绘制验证码字符''' 76 c_chars = get_chars() 77 strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开 78 79 font = ImageFont.truetype(font_type, font_size) 80 font_width, font_height = font.getsize(strs) 81 82 draw.text(((width - font_width) / 3, (height - font_height) / 3), 83 strs, font=font, fill=fg_color) 84 85 return ''.join(c_chars) 86 87 if draw_lines: 88 create_lines() 89 if draw_points: 90 create_points() 91 strs = create_strs() 92 93 # 图形扭曲参数 94 params = [1 - float(random.randint(1, 2)) / 100, 95 0, 96 0, 97 0, 98 1 - float(random.randint(1, 10)) / 100, 99 float(random.randint(1, 2)) / 500, 100 0.001, 101 float(random.randint(1, 2)) / 500 102 ] 103 img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲 104 105 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大) 106 107 return img, strs 108 109 在views中调用: 110 import io 111 from django.shortcuts import HttpResponse 112 from backend.utils import CheckCode 113 114 def check_code(request): 115 """ 116 获取验证码 117 :param request: 118 :return: 119 """ 120 stream = io.BytesIO() 121 # 创建随机字符 code 122 # 创建一张图片格式的字符串,将随机字符串写到图片上 123 img, code = CheckCode.create_validate_code() 124 img.save(stream, "PNG") 125 # 将字符串形式的验证码放在Session中 126 request.session["CheckCode"] = code 127 return HttpResponse(stream.getvalue())
富文本:
用处大约有两种
1. 在后台管理中使用
2. 在页面中使用,通常用来作博客