django框架 02
今日内容总结
- 静态文件及相关配置
静态文件
html页面使用的不经常改变的文件资源
插件资源、css资源、js资源、img资源
静态文件配置
seetings.py
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
静态文件动态解析
html页面上
{% load static %}
{% static '静态文件绝对路径' %}
- request对象方法
"""
form表单标签重要属性
action
method
网络请求方式
GET请求
POST请求
"""
request.method
获取当前请求方式,并且结果是纯大写的字符串
request.POST
获取请求体中携带的数据,结果是一个QueryDict,可以看成是字典
get() 值列表最后一个数据
getlist() 完整的列表
request.GET
获取url问号后携带的少量不敏感数据
get() 值列表最后一个元素
getlist() 完整的列表
- pycharm链接数据库
1.选择数据库
2.下载对应的驱动
3.填写信息连接即可
- django链接数据库
1.seetings.py
{
'NAME':'',
'HOST':'',
'POST':'',
'USER':'',
'PASSWORD':'',
'CHARSET':''
}
2.不同版本需要准备不同的模块
pymysql
mysqlclient
- django orm
ORM:对象关系映射
能够让不会SQL的python程序员使用面向对象的语法直接操作数据库
1.模型类
models.py
class Userinfo(models.Model):
name = models.CharField(max_length=32)
2.数据库迁移命令
python manage.py makemigrations
python manage.py migrate
3.数据库增删改查
models.Userinfo.objects.create()
models.Userinfo.objects.filter()
models.Userinfo.objects.update()
models.Userinfo.objects.delete()
4.外键
models.ForeignKey() 自动添加_id后缀
models.ManyToManyFiled() 自动创建第三张关系表
models.OneToOneField() 自动添加_id后缀
今日内容详细
一、静态文件及相关配置
1.先编写一个登录功能
①创建django项目并创建一个app(创建一个app一定要记得注册)
②在urls.py添加一组对应关系
③在app的views.py中编写登录核心逻辑
④利用三板斧与前端做交互
ps:
状况一: 注意当前计算机上跑了几个django项目,注意避免端口号冲突,那就有可能出现明明我的django项目改了,但没有反应,那可能用的是之前没有改的项目
状况二:由于计算机的版本可能不怎么适配,所以我们可能需要去settings中看一眼,首先去看app有没有注册,然后去看看templates
2.我们在访问django框架资源的使用之所以可以拿到数据是因为提前在urls.py中开设了相应的资源接口,如果访问不到资源那么就是没有开设相应的接口
3.静态文件
html页面上使用的不经常改变的资源(文件)
①第三方框架文件
②css文件
③js文件
④图片文件
针对静态文件资源一般都会放在static(静态的)文件夹内

当static目录下出现了很多不同类型的静态文件资源,那么还可以分类管理
others文件夹:
第三方框架文件
css文件夹:
所有的css文件
js文件夹:
所有的js文件
img文件夹:
所有的img文件
注意:‘静态文件资源配好之后遇到了一个问题’
代码操作:
①urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 登录功能
path('login/', views.login),
]
②views.py
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(request):
# 1.返回给前端浏览器一个登录页面
return render(request, 'login.html')
③login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<link rel="stylesheet" href="../static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="../static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登录页面</h1>
<div class="col-md-8 col-md-offset-2">
<form action="" >
<p>username:<input type="text" name="username" class="form-control"></p>
<p>password:<input type="text" name="password" class="form-control"></p>
<input type="submit" value="登录" class="btn btn-success bu=tn-block">
</form>
</div>
</div>
</body>
</html>


4.针对静态文件资源的访问也需要提前开设相应的接口
基础配置:
STATIC_URL = ‘/static/’ # 接口前缀:如果以后你想访问我这个网站下的静态资源,必须以/static/开头
# 静态文件资源配置
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]



5.接口前缀
STATIC_URL = '/static/' # 接口前缀
-------我拿着bootstrap-3.4.1-dist/js/bootstrap.min.js这个文件到static这个文件夹下面一找,有没有这个文件-------
------为什么STATICFILES_DIRS是个列表呢------
首先,在html文件里面引入js文件也好,引入css文件也好,引入图片也好,第三方框架也好,html页面引入的前缀一定要和STATIC_URL对应上,只有对应上了之后,你才有资格去框架中的静态文件中查找东西
6.动态解析(冷门知识点)
如果在html页面中有很多bootstrap源码,然后我们又想将接口前缀修改成别的,如果去html页面进行一个个更改是不可能的,所以有一个小方法
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css'%}">
二、请求方法(form表单注意事项)
URL:统一资源定位符(网址)
1.GET请求
朝别人索要数据,也可以携带额外的数据
携带参数的格式是:url?xxx=yyy&zzz=ooo&aaa=bbb

输入信息后,跳转到下面这个界面👇
上述携带数据的方式有两个限制
①数据只能是一些无关紧要的非敏感数据 (如果想要携带文件就得用POST请求了)
②数据大小有限制 2KB~4KB左右
GET请求没有请求体(HTTP数据格式)
2.POST请求
朝别人提交数据,也可以携带额外的数据
数据都是放在请求体(POST请求发送来的普通数据)中(所以它可以携带一些敏感的数据,比如密码),并且数据大小没有限制

3.form表单默认的数据提交方式是get
method = 'post' 这个可以改变数据提交的方式由get改为post(因为你不可能让别人看到你的密码啊,你用get请求提交数据,是会在路由的后面以?的形式写上去的 像上面的登录界面一样,数据会在?的后面显示出来username=xxx&password=xxx)
action 控制数据的提交地址
方式一:不写,超当前页面所在的地址提交
方式二:写后缀 /index/ 自动补全ip和port
方式三:写全称 https://www.baidu.com/
4.提交post请求前期需要去配置文件中注释一行代码
MIDDLEWARE = [
# 'django.middleware.csrf.CsrfViewMiddleware',
]
三、request对象方法
| request.method | 获取请求方式,结果是纯大写的字符串 (如:GET、POST) |
| request.POST | 获取POST请求发送来的普通数据(不包含文件) |
| reques.POST.get() | 默认只获取列表中最后一个数据值 |
| request.POST.getlist() | 获取键对应的整个列表,无论有几个数据值 |
| request.GET | 获取url后面携带的非敏感数据 |
| request.GET.get() | 默认只获取列表中最后一个数据值 |
| request.GET.getlist() | 获取键对应的整个列表,无论有几个数据值 |
-------关于login的html页面中的键的问题----------

------通过不同的请求方式触发执行不同的函数,如果是GET请求,就返回登录页面,如果是POST请求就获取用户名密码然后做判断,再做一些其他的操作------
如果请求方式是GET,那么说明只想拿回一个请求页面
-----这里面我们一经发现了request.POST是一个QueryDict(特殊的字典),那么我们想取里面单独的一个值,因为是字典,我们可以使用.get方法,然后明明字典里面的username对应的是一个列表,但取出来的却是一个字符串,原因是这个字典比较特殊,我们用.get取出的只能是列表里面的一个值,那列表里面的值就是字符串,所以它是字符串类型------

-----如果字典内有多个值,那么我们使用.get默认获取的是字典内最后一个值,如果想获取全部值,需要使用.getlist----

四、pycharm连接MySQL
------如果没有database,需要先安装插件------

1.查找pycharm提供的database按钮
左下角或右侧边栏或下载插件或卸载重装pycharm

2.首次连接数据库需要下载连接Mysql的驱动文件

3.简单的增删改查

五、django连接MySQL
django默认使用的是sqlite3,但是这款数据库一般只用于本地测试,功能较少
想要django与数据库链接,需要做以下配置:
1.配置文件中修改配置
settings文件中配置的修改
DATABASES = {
'default':{
'ENGINE':'django.db.backends.mysql',
'NAME':'day55',
'USER':'root',
'PASSWORD':'123',
'HOST':'127.0.0.1',
'PORT':3306, # 3306的mysql
'CHARSET':'UTF8' # 千万不要加_,加_会报错
}
}
------然后我们运行,会报错------

2.指定连接MySQL的模块(解决上面报错的问题)
如果是django1.11 版本需要在项目或者应用目录下的__init__.py中编写一行代码
import pycharm
pymysql.install_as_MySQLdb()
如果是django2.2 以上版本需要使用mysqlclient模块,并且去掉红框框内的配置即可
pymysql是从python 连接到 mysql的数据库服务器的接口,简单的理解为pymysql是python操作数据库的第三方模块
六、django orm
mysql里面是一些表,然后pymysql把我们这些表封装成字典,但是我们觉得字典还不够完美,于是我们用orm把这些表封装成对象(数据对象),对象比字典好在哪里?可以直接用点的方式操作数据,名称空间啊,属性啊都可以,其次当你想创建一张表的时候,需要自己执行与语句,create table,但是orm厉害了,这时候你只需要在自己的代码中创建一个类就可以了。你写一个类,通过orm能自动帮你把类转换成mysql中的一张表
ORM:对象关系映射
| orm能够将类 | 映射成 | 表 |
| orm能够将对象 | 映射成 | 记录 |
| orm能够将对象点属性 | 映射成 | 某个记录字段对应的值 |
orm的作用(orm最厉害的地方):ORM的存在可以让不会MySQL的python程序员,使用python的语法简单快捷的操作MySQL(是优点也是缺点,orm执行的sql语句没有自己写的效率高)
1.先去应用目录下的models.py编写模型类 (这个类就是表所以类名即表名)
类名就是表名
class User(models.Model): # 类似于定义了表名
# id int primary key auto_increment
id = models.AutoField(primary_key=True) # 类似于定义了主键
# name varchar(32)
name = models.CharField(max_length=32) # 类似于定义了普通字段
# pwd int
pwd = models.IntegerField() # 类似于定义了普通字段
但是类写完,我们并没有跟数据库做联动做交互,还需要执行两条命令,让它转换成表
2.数据库迁移/同步命令
① 将models中有关数据库的操作记录下来到migrations文件夹中 【它仅仅只是做了一个记录】
python38 manage.py makemigrations

-------执行完命令之后,我们发现migrations中多了一个py文件----

②将操作真正影响到数据库中
python38 manage.py migrate
'''当修改了models中与数据库相关的代码 都必须重新执行上述的两条命令'''
ps:可以简写 (makemigrations migrate)
也可以指定应用单独迁移/同步 如:makemigrations app01


---为什么我们创建的表名前面会加一个前缀呢?----
因为django会嵌入很多app应用,每个应用下都有一个业务逻辑,所以可能会出现不同的应用下出现了相同的表名,而在表名的前面加一个前缀,只是为了避免冲突
----那么黄色框框内是什么东西呢?----
这是django自动建的,它是django自带的


---如果django中有多个应用,而我只想同步某一个应用中的models文件,就需要在关键字后面加上应用的名字-----

3.表的主键在orm中,可以不写,orm会自动帮你添加一个id的主键
如果你需要主键的名称不叫id,只能自己创建

附加:
1. 字段里的参数是可以添加多个的
2. max_length=32 就是 varchar(32)
3. verbose_name 等价于 comment(给字段或表添加信息的)
4. 迁移数据库如果先执行migrate是行不通的,会提示,no migrations to apply, 是因为 orm之所以能起作用是因为读取了migrations中的日志文件,所以必须先执行makemigrations,让他在migrations中先生成文件,然后再执行migrate才能实现orm的同步
-----这里面的username是通过前端name字段决定的-----

----前端的键----

----使用orm查询数据----

七、orm 语法
ps:orm可以帮你把一条条数据封装成一个个对象
1.查
models.User.objects.filter() 结果可以看成是一个列表套数据对象(即列表里面套一条条数据)
filter是过滤的意思,类似于我们的where
如何获取对象,可以使用first()方法,如果没有值会返回None,我们if判断即可
----上面的意思大概就是:
一般我们是不会用索引取值的【res[0]】,因为索引取值如果我们在前端页面输入一个不存在的用户名密码,他会直接报错,所以我们用一个.first()的方法,去取里面的第一个值,然后做一个if判断,如果值存在,我们去取出它的各个字段,如果值不存在就返回用户名或密码错误

2.增
models.User.objects.create()
3.改
models.User.objects.update() 修改整条数据
models.User.filter(id=1).update(name='jasonNB') 筛选出id值为1的,将其name改为jasonNB
4.删
models.User.objects.filter(id=4).delete() 不加筛选条件就会删除整条数据
def login(request):
if request.method == 'POST'
username = request.POST.get('username')
password = request.POST.get('password')
# 查询数据
# select * from user where name='' and pwd=''
user_obj = models.User.objects.filter(name=username,pwd=password).first() # 获取第一条数据
print(models.User.objects.filter(name=username,pwd=password).query)
print(res) # <QuerySet [<User:User object(1)>]> 列表套数据对象
# user_obj = user_obj[0] 不推荐索引,因为索引错了会直接报错
if user_obj:
print(user_obj.id)
print(user_obj.name)
print(user_obj.pwd)
return HttpResponse('登录成功')
return HttpResponse("用户名或密码错误")
return render(request,'login.html')
----原本是这样的,但是更新了,能查询出来是<QuerySet [<User:User object(1)>]> 列表套数据对象----

八、orm 外键失联
1.MySQL
一对多
外键字段建在多的一方
多对多
外键字段建在第三张关系表
一对一
外键字段建在查询频率较高的表中
2.ORM
class Book(models.Model):
title = models.CharField(max_length=32)
# 书与出版社是一对多,数是多
publish = models.ForeignKey(to = 'Publish',on_delete=models.CASECADE) # 这句话的意思就是将来这个publish称为外键,和Publish这张表做关联关系
# 书与作者是多对多
authors = models.ManyToManyField(to='Authors') # 只要ManyToMany这个参数配好,orm会自动帮你配置好第三张表的
class Publish(models.Model):
pub_name = models.CharField(max_length=32)
class Authors(models.Model):
name = models.CharField(max_length=32)
detail = models.OneToOneField(to = 'AuthorsDetail',on_delete=models.CASCADE)
class AuthorDetail(models.Model):
phone = models.BigIntegerField()
一对多
外键字段建在多的一方
publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
多对多
外键字段可以直接写在某张表中,orm会自动帮你创建第三张表
authors = models.ManyToManyField(to='Authors')
---用来记录书和出版社的多对多的关系的表
----黄色的是主键,蓝色是外键----

----那么我们前面类里写的字段是publish,为什么这里是publish_id呢?----
因为这里他是提醒你,这张book表关联的publish表中的主键值,所以orm自动在publish的后面加了-id

一对一
外键字段建在查询频率较高的表中
detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)







浙公网安备 33010602011771号