1.注册功能
1.注册功能往往都会由很多校验性的需求 所以这里我们用到了forms组件
项目中可能有多个地方需要用到不同的forms组件 为了解耦合 但是创建一个py文件 专门用来存放项目用到的所有的forms组件
校验 用户名 密码 确认密码 邮箱
借助于钩子函数 校验用户名是否存在 密码与确认密码是否一致
2.创建路由 写视图函数
将实例化产生的forms类对象 利用模板语法传递到前端页面
再利用forms组件自动渲染前端获取用户输入的标签
3.用户输入数据后 采用ajax的方式朝后台提交数据
1.考虑到获取用户输入的input框可能会有很多 在同ajax获取的时候 可能会比较繁琐
借助了form标签有一个方法 自动将内部所有的普通键值 打包成一个容器类型
4.用户头像前端动态展示
利用内置对象 文件阅读器 new FileReader
等待什么什么加载完毕再执行 onload
window.onload
fileReader.onload = function(){
文件阅读器加载完毕之后 再执行的操作
}
5.针对ajax提交的数据 后端在返回信息的时候 通常都是一个字典
在创建数据的时候利用**直接打散字典的形式 传输数据
6.将错误的信息传递给前端
前端渲染错误信息的时候 遇到了一个问题 如何将对应的信息渲染到对应的input框下面的span标签中
研究forms组件渲染的input框的id值的特点 id_字段名
发现后端传过来的字典的key就是一个个的字段名 自己拼接处id值
2.登录功能
1.前端页面搭建
图片验证码
2.图片验证码
img标签 src可以接收的数据
1.图片的具体路径
2.图片的二进制数据
3.后端url(自动朝该url发送get请求)
3.后端代码推导
操作图片的模块pillow
4.完成后跳转到网站首页
展示网站所有的博客内容
django
django是什么
web框架 django是一款专门用来开发app的web框架
框架 就是类似于提前帮你搭建好整个项目的基础架构
纯手撸的web框架
统一接口
先砸钱 先让用户对你这个软件产生依赖 然后你再慢慢的抽血
共享单车
HTTP协议 >>> sql语句
为什么要有HTTP协议 一个服务端要服务N多个不同的客户端 如何保证数据的正常交互
为什么要有sql语句 一个服务端要服务N多个不同的客户端 如何保证数据的正常交互
web框架
django
flask
三行代码
tronado
自己去百度收一收
django版本问题
django == 1.11.11
requiretment.txt
django == 1.11.11
django == 1.11.11
django == 1.11.11
django == 1.11.11
django == 1.11.11
django == 1.11.11
django == 1.11.11
django == 1.11.11
django == 1.11.11
django基本操作命令
创建一个django项目
django-admin startproject 项目名
启动django项目
python manage.py runserver
创建应用(app01/app02) web option
python manage.py startapp 应用名
数据库迁移命令
python manage.py makemigrations
python manage.py migrate
# 报错 中文的问题
# 报错 django源码多了一个逗号
浏览器 >>> nignx + web服务网关接口(wsgiref,uwsgi) >>> 中间件(全局性的功能) >>> 路由层 >>> 视图层 >>> 模板层 + 模型层(ORM查询) + 数据库
web服务网关接口
django默认的是wsgiref
上线之后该用uwsgi
WSGI与wsgiref,uwsgif关系
前者是协议 后者是实现该协议的功能模块
请求到达django后端和响应离开django后端都必须结果中间件
django默认有七个中间件 并且支持用户自定义中间件
自定义中间件有五个可以自定义的方法
需要掌握
process_request
process_response
需要了解
process_view
process_exception
process_template_response
# 形参中有response的 一定要将该形参返回
# 写好的中间件 一定要在配置文件中注册
设计思想
importlib
反射
# 都是操作字符串
路由层
url(r'^index/',view.index)
1.路由匹配
url的第一个参数 是一个正则表达式
在匹配的时候 有一个特点 一旦匹配上了 会立刻停止匹配 执行路由对应的方法
2.无名分组(位置参数)
url(r'^index/(d+)',view.index)
3.有名分组(关键字参数)
url(r'^index/(?P<year>d+)',view.index)
4.反向解析
静态文件的配置
url(r'^index/',view.index,name='index') # 这个名字一定要是在整个django项目中唯一
{% url 'index' %}
reverse('index')
url(r'^index/(d+)',view.index)
{% url 'index' 1 %}
reverse('index',args=(1,)) # 容器类型 哪怕只有一个元素 你也习惯性的加一个逗号
url(r'^index/(?P<year>d+)',view.index)
{% url 'index' 1 %}
{% url 'index' year=1 %}
reverse('index',args=(1,)) # 容器类型 哪怕只有一个元素 你也习惯性的加一个逗号
reverse('index',kwargs={'year':1,}) # 容器类型 哪怕只有一个元素 你也习惯性的加一个逗号
5.路由分发(******)
include
url(r'^应用名1/',include('应用名1.urls'))
url(r'^应用名2/',include('应用名2.urls'))
6.名称空间
url(r'^应用名1/',include('应用名1.urls',namespace='应用名1'))
url(r'^应用名2/',include('应用名2.urls',namespace='应用名2')))
reverse('应用名1:别名')
reverse('应用名2:别名')
视图层
HttpResponse
render
redirect
JsonResponse
FBV与CBV
只要是视图函数 一般情况下都需要定义一个形参request
CBV的书写及内部原理
from django.views import View
class MyReg(View):
def get(self,request):
pass
url(r'^index/',MyReg.as_view())
# url(r'^index/',view)
view里面
1.实例化产生自己写的类的对象
2.对象点dispatch方法
dispatch里面
1.先确认请求方式(默认八个)
2.反射获取方法的内存地址
3.加括号执行对应的方法
模型层
模板语法
变量相关 {{}}
逻辑相关 {%%}
1.过滤器
|length
|default
|add
|date
|filesizeformat
|slice
|truncatewords
|truncatechars
|safe
2.标签
{% if aaa %}
{% elif %}
{% else %}
{% endif %}
{% for %}
{{ forloop }}
{% endfor %}
{% with %}
{% endwith %}
3.自定义过滤器及标签
1.在应用中要键一个名字必须叫templatetags
2.任意名称的py文件
3.固定写两行代码
from django.template import Library
register = Library()
@register.filter
@register.simple_tag
4.模板的继承与导入
继承
模板中需要提前划定号区域
{% block '名字' %}
模板内容
{% endblock %}
子板中使用
{% extends '模板的名字'%}
{% block '名字' %}
子板内容
{{ super.block }}
{{ super.block }}
{{ super.block }}
{% endblock %}
模板的导入
{% include '模板名' %} # 类似于导入模
模型层
查询语句
单表的查询
类名.objects.
必知必会13条
all()
filter()
get()
values()
values_list()
first()
last()
order_by()
reverse()
count()
exists()
distinct()
exclude()
神奇的双下划线
price__lt
__gt
__lte
__gte
__in
__range
title__startswith
__endswith
__contains
__icontains(******)
create_time__year
__month
外键字段的增删改查
一对多
create(publish=publish_obj)
create(publish_id=1)
# 默认是级联更新 级联删除
多对多
add()
add(1)
add(1,2)
add(author_obj)
add(author_obj,author_obj1)
remove()
# 同理
set()
set([1,])
set([1,2])
set([author_obj,])
set([author_obj,author_obj1])
clear()
跨表查询
正向查询按字段
反向查询按表名小写
基于对象的(子查询)
1.先获取一个对象
2.利用对象点点
book_obj.publish.name
book_obj.authors.all()
author_obj.author_detail.phone
publish_obj.book_set.all()
author_obj.book_set.all()
author_detail_obj.author.name
基于双下滑线(连表查询)
models.Book.objects.filter(pk=1).values('publish__name')
models.Book.objects.filter(pk=1).values('authors__name')
models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
models.Publish.objects.filter(book__pk=1).values('name')
聚合查询
关键字 aggregate
from django.db.models import Avg, Max, Min, Sum, Count
分组查询
关键字 annotate
参考博客练习题
F与Q查询
F 能够获取表中的某个字段对应的数据
库存数大于卖出数的书
Q 能够改变查询条件
与 filter(**kwargs)
或 filter(Q(xxx='yyy')|Q(yyy='ooo'))
非 filter(~Q(xxx='ooo'))
ps:
q = Q()
q.connector = 'or'
q.children.append('xxx','ooo')
q.children.append('yyy','zzz')
filter(q)
django与ajax
前后端传输数据的编码格式
urlencoded
username=jason&age=18
formdata
application/json
{"username":"jason"}
form表单
ajax(******)
ajax基本语法
$.ajax({
url:'',
type:'post',
data:{'name':'jason'}
success:function(data){
alert(data)
}
})
ajax提交json格式
data必须是json格式的数据
contentType需要指定成application/json
ajax提交文件格式
data直接写formdata对象
还需要指定两个参数为flase
contentType
processData
cookie与session
中间件
class User:
username
password
1 jason 123
2 egon 123
3 tank 123
4 oscar 123
class Permission:
title
url
1 查看用户 check_user/
2 增加用户 add_user/
3 编辑用户 edit_user/(d+)/
4 删除用户 delete_user/(d+)/
...
class User2Permission
user
permission
1 1 1
2 1 2
3 1 3
RBAC 基于角色的权限管理()
class User:
username
password
1 jason 123
2 egon 123
3 tank 123
4 oscar 123
class Role:
title
1 保安队长
2 保洁阿姨
3 CEO
4 管理员
class Permission:
title
url
1 查看用户 check_user/
2 增加用户 add_user/
3 编辑用户 edit_user/(d+)/
4 删除用户 delete_user/(d+)/
...
class User2Role
user
role
1 1 3
2 2 2
3 3 1
4 4 2
class Role2Permission
role
permission
1 3 1
2 3 2
3 3 3
4 3 4
白名
黑名单