第二周内容总结
第一天
-
django主要目录结构
- app目录 app文件目录 migrations文件夹 存放orm操作数据库的命令 admin.py django自带的后台管理功能 apps.py 每个应用的独立标识 models.py 模型层 tests.py 测试文件 views.py 视图函数 也叫视图层 django项目同名文件夹目录 urls.py 路由层 settings.py 配置文件 wsgi.py 依赖于wsgiref模块的socket启动部分 static 静态文件夹 templates 存放的是html页面 也叫模板层 manage.py 启动文件 db.sqllite django自带的小型数据库 #记住一定要去注册 在settings 的 INSTALLED_APPS[ 'app01.apps.App01Config', #简写 'app01' ] templates 路径配置 把模板层放在全局 TEMPLATES=[ 'DIRS':[os.path.join(BASE_DIR,'templates')] ] #DEBUG 生产环境时候记得要写False ALLOWED_HOSTS = [*] 上线之后没其他需要写* 写主机名
-
小白必回三板斧
HttpResponse 返回给前端一个普通文本数据 render 返回给前端一个html页面 并支持jinja2语法 可以传值给html页面字典形式 locals都传过去 redirect 重定向一个页面 比如百度 可以/index/ 这样写 前面自动加上ip和端口
-
静态文件配置
1.创建一个static文件夹 存放静态文件 2.settingsATIC_URL='static' 接口前缀 3.ettings里配置 STATICFILED_DIRS=[os.path.join(BASE_DIR,'static')] 想访问静态资源,需要以STATIC_URL开头,然后这个里面的内容才会暴露给你 4.如果静态文件经常编或者引入静态文件的地方很多,那么接口这块不能写死 可以这么写 { %load% static} <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/xxx/xxx'%}">
- 网络请求方法
# url:统一资源定位符 GET 索要数据 get请求也可以携带额外的参数但是有大小限制 并且是在url中携带 url?xxx=yyy&aaa=bbb POST 提交数据 post请求一般携带的都是敏感性数据 数据没有大小限制并且存储在请求体
-
request对象方法
request.method 获取当前请求方法 request.GET 通过url后面加问号然后k/v的形式传输过来 获取当前GET请求 request.GET.get 如果有多个username key 他会选择最后一个 request.GET.getlist 多个key 他会选择全部 request.POST 目前只能前端通过form表单传输过来 里面的method指定成post 如果是获取的是空字典 那么是因为前端form表单里面的input没有指定name 就相当于字典没有key 获取对其POST请求 request.POST.get request.POST.getlist
-
pycharm连接mysql
点击database 然后点点点
-
django连接mysql
1.settings里配置DATABASES=[] 2.任意__init__ 里面加上一句 inport pymysql pymysql.install_as_mysqldb() 这句话的意思是django默认是他自带的那个小型数据库 给他换咯
第二天
-
django orm简介
1.什么是orm 对象关系映射 2.为什么要用orm 为了让不会qal语句的程序员使用面向对象的语法即可操作数据库 但是他自动生成的sql语句有时候效率不是很高 可能用explain 发现级别才是all 3.类 ------- 表 对象 ------- 一行行记录 对象.属性 --- 记录某个字段对应的值
-
orm创建表 (迁移数据库两个重要命令)
1.在models层里创建类 对应表 里面创建属性 对应字段 2.创建完 执行 python3 manage.py makemigrations 在migrations文件夹生成一个记录,现在小本本mifrations记上 然后 python3 migrate 同步到数据库
-
orm字段增删改查
增删改查 直接改语句 然后重新迁移数据库就ok了 但是注意如果里面有数据 添加新字段要注意 他不知道原来的数据的新添加的字段的值是多少 可以通过两种方式解决 添加字段时候设置可以为空 那么之前那个数据的新添加的字段就是null 第二种方式 添加字段时候 设置default 默认值 之前的 # 当表中已经有数据存在的情况下如果添加新的字段那么需要设置null或者default password = models.IntegerField(verbose_name='密码',null=True) # pwd int comment '密码' age = models.IntegerField('年龄',default=18)
-
orm记录增删改查
#查 models.book.object.all() 返回的是列表淘数据对象,可以加一个.first 然后 获取的数据直接 .字段名就可以获取值了 models.book.object.fiter(pk=1) 主键等于1 增 models.book.object.create(name='xxx',pwd='123') obj=models.book(name='xxx',pwd='123') obj.name='aaa' #这种方法 只是类产生对象 然后修改在保存 obj.save() 删 models.book.object.filter(pk=5).delete() 改 models.book.object.filter(pk=5).update(name='aaa')
-
orm外键的创建
一对多 'xxx'= models.Foreignkey(to=表名) #建在多的一方创建外键 在实际表中publish会自动加上_id后缀(自己在定义的时候不要加) 多对多 'xxx'=models.manytomanyfiekd(to=表名) #建在多的一方 不会创建字段 而是会告诉orm创建第三张表存放对应关系 一对一 'xxx'=models.onetoonefiekd(to=表名) #建在查询频率较高的表中 自动加_id后缀
第三天
-
简易版本django请求生命周期流程图(重要)
1.浏览器发送请求(http数据格式的) 2.web服务网关接口 (铲粪并打包http数据格式 wsgiref模块 但是上线不会用 会改成uwsgi) 3.到了整个django 的 中间件(类似于django的保安)进来出去都要经过他 4.进入路由层 5.进入视图层 6.模板层 7.模型层
-
路由匹配
url(r'^index/',views.index) #url 前面的是正则表达式 后面是视图函数内存地址
-
无名有名分组
正则表达式加一个括号则为无名分组 url(r'^index/([0-9]{2})',views.index) 正则表达式加一个括号里面起个名字问号加大写的P则为有名分组 url(r'^index/(?P<year>[0-9]{2})',views.index) 不能混用
-
反向解析
在路由层写正则表达式起一个name名字 #通过标记解析出一个结果 该结果可以访问到标记所在的那一行地址 url(r'^login/',views.login,name='my_login'), 后端解析 #结果index/ from django.shortcuts import reverse print(reverse('my_login')) 前端解析 #结果index/ <a href="{% url 'my_login' %}">点我1</a> #记得引号
-
无名有名解析
# 无名分组的反向解析 url(r'^login/(\d+)/',views.login,name='my_login') 后端 _url = reverse('my_login',args=(111,))#除了指定name 还需要指定一个参数元组格式的 print(_url) # /login/111/ 前端 {% url 'my_login' 1 %} # 有名分组的反向解析 url(r'^login1/(?P<xxx>\d+)/',views.login1,name='my_login1') 后端 _url = reverse('my_login',kwargs={'xxx':123}) _url = reverse('my_login',args=(123,)) #这样写也ok print(_url) # /login/123/ 前端 {% url 'my_login' xxx=1 %} """其实无名有名反向解析可以使用通用的方式""" 都可以使用无名分组的反向解析
-
路由分发
一个django项目 多个app 可以采用路由分法 """ django支持所有的应用都可以拥有自己的 urls.py templates文件夹 static文件夹 也就意味着多人协同开发变得更加的简单了 """ #(斜杠后面千万不要加$符) url(r'^app01/',include('app01.urls')), url(r'^app02/',include('app02.urls')), 子路由正常写
-
名称空间
因为多个app路由可能起了相同的名字 那么在路由分发时 需要指定namespace url(r'^app01/',include('app01.urls',namespace='app01')), url(r'^app02/',include('app02.urls',namespace='app02')), 也可以别让他重复 比如 app01_index 解析时候 reverse('app01:index')
-
伪静态
静态页面 数据写死的 不怎么改变的 伪静态页面 看似是文件其实是动态网页 这么做事为了提高网站被搜索引擎收录的概率 将路径后缀改为.html形式即可
-
虚拟环境
虚拟环境能够实现针对不同的项目配备专属的编程环境 创建虚拟环境相当于重新下载了一个新的解释器 虚拟环境的唯一表示是venv文件夹
第四天
-
小白必会三板斧
所有视图函数必须返回一个HttpResponse对象
-
JsonResponse
""" 前后端不分离 django写项目(前端直接使用模板层及模板语法) 前后端分离 django写项目(前端使用其他框架和语言) 不同编程语言之间如何交互??? json格式数据 python中序列化反序列化的方法 dumps() loads() js中序列化反序列化的方法 JSON.stringfy() JSON.parse() """ 先导入from django.http import JsonResponse 传输字典 json_dumps_params 打散成关键字参数传给dumps 'ensure_ascii':False 不让他中文进行转码 return JsonResponse(d,json_dumps_params={'ensure_ascii':False}) 传输列表等 safe False return JsonResponse(l,safe=False)
-
form表单发送文件
1.method必须是post 2.enctype参数必须是multipart/form-data request.FILES获取文件类型的数据 一次只能获取一次 如果想获取多个需要前端指定 <input type="file" name="file"> 只能获取一个 <input type="file" name="file" multiple> 可以一次性获取多个 后端获取文件数据 request.FILES.get('名字') #获取文件对象单个 request.FILES.getlist() #获取多个文件对象
-
FBV与CBV
路由配置 #FBV路由配置 url(r'^index/',views.index), #CBV路由配置 url(r'^login/',views.Mylogin.as_view()) #配置有点不一样和FBV FBV 基于函数的视图 (前后端不分离) def index(request): return HttpResponse(...) CBV 基于类的视图 (前后端分离) from django.views import View #先导入模块 class Mylogin(View): #需要继承view def get(self,request): return HttpResponse('get请求') def post(self,request): return HttpResponse('post请求') 发现了路由层调用一个函数 这个函数是哪的 因为是类调用直接去类找,没,去他的父类中找找到了, as_view retrun了 view这个函数 view这个函数 定义了一个类的对象 return了 对象的dispatch方法 这个方法对象 没有 类没有 父类有 这个方法把请求的方法转小写并判断是否在八个默认方法里面 在利用反射获取对象中具有与请求方法相同的方法名 内存地址赋值给handler 不在返回一个报错方法 最终执行这个handler并return 然后return 对象名()调用
-
模板层语法传值
给前端传值 python 支持全部数据类型给前端传值 前端获取 需要用句点式获取 比如{{d.name}} {{}} # 跟变量名相关 {%%} # 跟功能逻辑相关 for if
-
模板语法之过滤器
相当于内置函数 格式 <p>{传过来的变量名|过滤器名称:有参数就写没有就不写}</p> |length 统计长度 |add:123 加上 整形加法运算 字符串 拼接 |default:False是我 前面的是true or false |date:'Y-m-d H-i-s' 日期格式 |truncatewords:截取的单词个数 根据单词截取 空格区分 不包括三个点的位置 |truncatechars:截取的字符个数 根据字符截取 包括三个点的位置 |filesizeformat 转成kb k m等容易识别的字符数据大小格式 |safe 转义 前端代码后端写 前端正常显示 后端也可以自动转义 from django.utils,safestring import mmark_safe res=mark_safe(前端代码)
-
模板语法之标签
<p>标签:其实就是流程控制 if判断 for循环</p> {% for foo in s %} {% if forloop.first %} #第一次循环执行这个 <p>这是第一次循环</p> {% elif forloop.last %} #最后一次循环执行这个 <p>这是最后一次</p> {% else %} <p>继续!!!</p> {% endif %} {% empty %} <p>传递过来的数据是空的</p> {% endfor %} forloop 里面的参数 count0 从索引o开始 count 从索引1开始 revcounter 倒序 一直到索引1 revcounter0 倒序 一直到索引0 first 第一个为true 其他为false last 最后一个为true 其他为false
第五天
-
自定义过滤器、标签、inclusion_tag(BBS作业用一次)
1.在应用文件夹(app)下创建一个名字必须叫templatetags文件夹 2.在创建的文件夹下创建一个任意名称的py文件 比如mytag 3.在该py文件内先固定写两句话 from django import template register = template.Library() @register.filter(name='gailun') 自定义过滤器 @register.simple_tag(name='nuoke') 自定义标签 @register.inclusion_tag('myul.html',name='my_ul') 自定义inclusion_tag 自定义过滤器:在html页面调用这个过滤器名称 他去自定义的过滤器找对应的函数 把函数返回值丢到调这个过滤器的html页面,最多只能传两个参数 自定义标签;在html页面调用这个标签名称 他去自定义的标签找对应的函数 把函数返回值丢到调这个标签的html页面 inclusion_tag:在html页面调用这个,也会去找对应的函数 但是他的返回值放在一个html页面(导航条 from表单等等,不是一个完整的页面),这个小页面塞到调这个的位置上 使用时候记得 {% load lol %} 一定要先加载才能使用 {{ s|gailun:111 }} #指定过滤器的名字 {% nuoke 1 2 3 4 %} #调用标签时记得 参数不要加逗号 {% my_ul 10 %} #不要加: ,
-
模板的继承(django前后端结合 那么使用频率较高)
很多页面大部分相同 只有一小部分不一样 那么就可以 使用模板继承 """ 母版中最少应该有三块区域 {% block content %} 可以根据页面内容的布局写多个 {% endblock %} {% block css %} #css 样式的 {% endblock %} {% block js %} #js样式 {% endblock %} """ 使用时候 {% extends 'home.html' %} {% block css %} <style> h1{ color: red; } </style> {% endblock %}
-
模板的导入(类似于python中导入模块)
类似于导模块 该模板不应该是一个完整的页面 而是一个局部页面 很多地方都需要使用的情况下可以使用模板的导入 可以多次导入 {% include 'menu.html' %}
-
模型层(ORM语句) 查询关键字
测试环境 去manage.py前四行 1.all 查询全部 2.filter 等于where 3.values 等于查询的字段 结果是列表套字典 4.values_list 等于查询的字段 结果是列表套元组 5.first 与 last 取第一个数据对象和最后一个数据对象 6.get方法直接获取到数据对象 但是查询不到结果会报错 filter 不会报错返回空的queryset 7.exclude 取反 条件不满足的全都执行 8.order_by 排序 默认升序order_by('price') 降序order_by('-price') 9.reverse 翻转 必须有顺序在可以翻转 10.distinct 去重 记得注意主键值 主键值一定不一样 11.count 计数 查询的结果计数 12.exists 判断结果是否有数据 13. create update delete 如何查看sql语句 1.如果当前对象是queryset那么可以直接点query查找该对象内部SQL语句 2.配置文件(只要执行orm语句都会自动打印SQL语句) LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
-
ORM之神奇的双下划綫查询
字段名__gt=值 某个字段大于某个值的数据对象 字段名__gte=值 某个字段大于等于某个值的数据对象 字段名__lt=值 某个字段小于某个值的数据对象 字段名__lte=值 某个字段小于等于某个值的数据对象 字段名__in=['123','234'] 某个字段等于值1或值2或值3 的数据对象 加引号看前提 ,如果是浮点型要加引号,因为python对浮点数这块不够精确 字段名__range=(200,500) 某个字段的值在200-500之间 的数据对象 字段名__contains='p' 某个字段的值包含字母'p'之间 的数据对象 区分大小写 字段名__icontains='p' 某个字段的值包含字母'p'之间 的数据对象 不区分大小写 字段名__startswith='人' 某个字段以'人'开头的数据对象 字段名__ebdswith='的' 某个字段以'的'结束的数据对象 #前提是日期类型 字段名__year=2021 某个字段的年份为'2021'的数据对象 字段名__month=11 某个字段的月为'11'的数据对象
-
-
-