django初识
创建django#
命令行操作#
创建django项目
# 可以先切换到对应的盘django-admin startproject 项目名目录结构
"""├──项目名文件夹├──manage.py django入口文件├──db.sqlite3 django自带的小型数据库├──项目名文件夹├──settings.py 配置文件├──urls.py 路由与视图函数对应关系(路由层)└──wsgi.py wsgiref模块├──app01文件夹├──admin.py django后台管理├──apps.py 注册使用├──mingrations文件夹 数据库迁移记录├──models.py 数据库相关的 模型类(orm)├──tests.py 测试文件└──views.py 视图函数(视图层)"""启动django项目
# 先切换到项目目录下 cd /项目名python3 manage.py runserver # http://127.0.0.1:8000/创建应用
"Next,start your first app by running python manage.py startapp [ app_label]."python manage.py startapp 应用名
pycharm操作#
创建应用
- pycharm左下角的Terminal用命令创建
- pycharm上方选项中的
Tools-Run>manage.py>Task...( Ctrl + Alt + R )
命令行和pycharm创建的区别#
命令行创建不会自动有templates文件夹 需要你手动创建
pycharm会自动帮你创建 并且还会自动在配置文件中配置对应的路径
静态文件配置#
静态文件动态解析#
应用#
应用创建后需要在配置文件setting中注册
django小白必会三板斧#
HttpResponse#
返回字符串类型的数据
render#
返回html文件的
传值的两种方式
更加的精确 节省资源 需要谁就传谁
user_dict = {'user':'jqm','pwd':'jqmkfc'}return render(request,'xxx.html',{'data':user_dict.'mmm':123}) # 接下来在html文件中{{ data }}的形式就可以获取值当你要传的数据特别多的时候用这个
return render(request,'xxx.html',locals()) # locals会将名称空间中所有的局部变量传递给html页面
redirect#
重定向
中间件介绍#
在前期我们使用django提交post请求的时候 需要去配置文件中注释掉一行代码 否则会报403
request对象初识#
Django链接数据库(MySQL)#
默认用的是sqlite3
django链接MySQL#
第一步配置文件中的配置
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'day60','USER': 'root','PASSWORD': 'jqmkfc039988','HOST': '127.0.0.1','PORT': 3306,'CHARSET': 'utf8'}}代码声明
django默认用的是mysqldb模块链接MySQL,但是该模块的兼容性不好 需要手动改为用pymysql链接
在项目名下的 init.py 或者任意的应用名下的init文件中书写以下代码即可
import pymysqlpymysql.install_as_MySQLdb()
Django ORM#
在models.py下书写
# verbose_name='对字段的一个解释' 都可以加class User(models.Model):# id int primary_key auto_increment# 由于一张表中必须要有一个主键字段并且一般情况下都叫id字段# 所以orm当你不定义主键字段的时候orm会自动帮你创建一个名为id主键字段# 也就意味着后续我们在创建模型表的时候如果主键字段名没有额外的叫法那么主键字段可以省略不写id = models.AutoField(primary_key=True)# username varchar(32) CharField必须指定max_length参数 不指定会报错username = models.CharField(max_length=32)# password intpassword = models.IntegerField()# price 小数 max_digits=8 decimal_places=2 总共8位 小数点后面占2位price = models.DecimalField(max_digits=8, decimal_places=2)# auto_now_add=True 每一次数据创建出来 这个字段会自动更新 多用于注册时间 上次登录时间publish_data = models.DateField(auto_now_add=True)数据库迁移命令
python manage.py makemigrations # 将操作记录记录到小本本上(makemigrations文件夹)python manage.py migrate # 将操作真正的同步到数据库中# 只要你修改了models.py中跟数据库相关的代码 上述两条命令就要重新执行一次
案例:#
编辑功能:点击编辑按钮朝后端发送编辑数据的请求
先将数据库中的数据全部展示到前端 然后给每一个数据两个按钮 编辑和删除
问题:如何告诉后端用户想要编辑哪条数据?
- 将编辑按钮所在的那一行数据的主键值发送给后端
- 利用url问号后面携带参数的方式
删除功能
删除数据内部其实并不是真正的删除,仅仅只是将字段修改一个状态
我们会给数据添加一个标识字段用来表示当前数据是否被删除 例如is_delete
中的Flase改成True
orm创建表关系#
在django1.x版本中外键默认就是级联更新删除的
在django2.x版本中外键需要加上 on_delete=models.CASCADE null=True
多对多三种创建方式#
全自动:利用orm自动帮我们创建第三张关系表
纯手动
半自动 可以试用orm的正反向查询 但是没法使用add,set,remove,clear这四个方法
总结:需要掌握的是全自动和半自动 为了拓展性更高 一般都使用半自动 不过只是查询的时候省事了 有需要的话还是全手动吧
分页器#
附件:自定义分页器的代码#
Form组件#
- 生成页面可用的HTML标签
- 用户提交校验功能
- 保留上次输入内容
校验数据#
渲染标签#
form组件只会帮你渲染获取用户输入的标签 input select radio checkbox 不会帮你渲染提交按钮的
生成一个空对象,传到前端去
前端用空对象做操作
推荐使用 代码书写简单 拓展性也高
{% for form in form_obj %}<p>{{ form.label }}:{{ form }}</p>{% endfor %}
代码书写极少,但是封装程度太高 拓展性太差 一般只在本地测试中使用
{{ form_obj.as_p }}{{ form_obj.as_ul }}{{ form_obj.as_table }}
可拓展性强 但是需要书写的代码太多 一般情况不用
<p>{{ form_obj.username.label }}:{{ form_obj.username }}</P><p>{{ form_obj.password.label }}:{{ form_obj.password }}</P><p>{{ form_obj.email.label }}:{{ form_obj.email }}</P>
钩子函数(HOOK)#
钩子函数在forms组件中就类似于第二道关卡 能够让我们自定义校验规则 在特定的节点自动触发完成相应操作
在forms组件中有两种钩子函数
局部钩子
当你需要给某个字段增加校验规则的时候可以使用
全局钩子
当你需要给多个字段增加校验规则的时候可以使用
案例:
form组件其他参数及补充知识点#
其他类型渲染#
cookie和session#
cookie的由来#
都知道HTTP协议是无状态的,无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
一句有意思的话来描述就是人生只如初见,对服务器来说,每次的请求都是全新的。
状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。
cookie就是保存在客户端浏览器上的信息 下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息
什么是Cookie#
Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
Cookie的原理#
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
查看Cookie#
django操作cookie 需要借助HttpResponse对象
session由来#
Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”,但是Cookie以文本的形式保存在本地,自身安全性较差,所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本。
session就是保存在服务端上的信息,也可以在其他地方储存,表,文件,缓存等等...表现形式一般都是k:v键值对(可以有多个),需要基于cookie才能工作
给客户端返回的是一个随机的字符串 sessionid:"随机字符串"
默认情况下session需要django一张diango_session表 数据迁移命令后会自动生成 django默认session的过期时间是14天
CBV添加装饰器的三种方式#
Django中间件#
process_request#
- 请求来的时候需要经过每一个中间件里面的
process_request
方法 结果的顺序是按照配置文件中注册的中间件的顺序从上往下依次执行 - 如果中间件里面没有自定义的方法,那么直接跳过执行下一个中间件
- 如果该方法返回了
HttpResponse
对象,那么请求将不再继续往后执行 而是直接原路返回(校验失败不允许访问...)
process_request
方法就是用来做全局相关的所有限制功能 (比如没登录 黑名单 ...)
process_response#
响应走的时候需要经过每一个中间件里面的
process_response
方法 该方法有两个额外的参数request
和response
该方法必须返回一个
HttpResponse
对象 默认返回的就是response
对象也可以返回自己的 返回后就会不管后面的视图函数返回的是什么 都会变成这里设置返回的 (狸猫换太子)
顺序是按照配置文件中的注册了的中间件从下往上依次经过 如果你没有定义的话 直接跳过执行下一个
如果在第一个process_request
方法就已经返回了HttpReponse
对象,那么响应走的时候就会直接走同级别的process_response
返回
flask框架也有一个中间件但是它的规律是只要返回数据了就必须经过所有中间件里面类似process_response
的方法
了解知识点#
process_view#
路由匹配成功之后视图函数之前,会自动执行中间件里面的该方法 顺序是按照配置文件中的注册了的中间件从上往下的顺序依次执行
process_template_reponse#
参数 request,response
返回的是HttpResonse
对象有render
属性的时候才会触发 顺序是按照配置文件中注册了的中间件从下往下往上的顺序依次执行
process_exception#
参数 request,exception
当视图函数出现异常的情况下触发 顺序是按照配置文件中注册了的中间件从下往下往上的顺序依次执行
如何自定义中间件#
csrf跨站请求伪造#
js代码#
csrf相关装饰器#
Auth模块#
Auth模块功能#
django在启动之后就可以直接admin路由,需要输入用户名和密码,数据参考的就是auth_user表,并且还必须是管理员用户才能进入
创建超级用户(管理员)
auth提供的方法
auth提供的登陆认证装饰器