一、Django静态文件配置
##settings.py##
静态文件配置:
STATIC_URL = '/static/'
# 静态文件配置
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
# 暴露给外界能够访问服务器静态文件夹下面所有的资源
STATIC_URL = '/xxx/' # 接口前缀 跟你的静态文件夹的名字一点关系都没有
# 默认情况下这个前缀跟静态文件夹名字一样!!!
# 静态文件配置
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'), # 就是你的静态文件夹路径
os.path.join(BASE_DIR,'static1'),
os.path.join(BASE_DIR,'static2')
]
# ps:会依次查找列表中所有的静态文件路径 找到的话立刻停止,都没有找到返回404静态文件目录结构:
项目目录-->static-->{css, js, images, bootstrap-3.3.7}
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>二、form表单提交数据的动作两种方式
<input type='submit'> <button></button>
三、form提交数据的地址如何指定及方式
action属性控制提交的地址:
方式:
1.全路径
<form action="http://127.0.0.1:8000/login/">
2.只写路径后缀
<form action="/login/">
3.不写 (默认往当前路径提交)
form表单默认是get请求;四、案例-根据客户端请求方式的不同执行不同的逻辑代码
根据客户端请求方式的不同执行不同的代码:
def login(request):
print(request.method) #获取用户提交的请求方式,全是大写的字符串
if request.method == 'GET':
return render(request,'login.html') #get的话返回登录页面
return HttpResponse('ok') #如果是post的话进行其他操作def login(request):
# 获取用户端提交的请求方式
print(request.method) # 拿到的请求方式是全大写的字符串
if request.method == 'POST':
print(request.POST) # 你就把它当成一个大字典里面存放了客户端post提交的所有的数据
# request.POST:< QueryDict: {'username': ['jason'], 'password': ['123']} >
print(request.POST.get('username')) # value虽然是个列表但是获取value的时候拿到却是单个元素
# 默认只会取value列表里面的最后一个元素
# request.POST:<QueryDict: {'username': ['jason', 'egon'], 'password': ['123']}>
print(request.POST.getlist('username')) # 要想一次性获取value列表里面所有的数据需要用getlist()
# ['jason', 'egon']
print(request.POST['password']) # 不推荐使用该方法获取数据
return HttpResponse('OK')
return render(request,'login.html')
获取value列表里面所有的元素需要使用getlist 应用场景:用户的爱好 多选框;
get只会获取到value列表的最后一个元素;五、django连接数据库
1、需要修改配置文件
##settings.py##
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day55',
'HOST': '127.0.0.1',
'PORT': '3306',
'USER': 'root',
'PASSWORD': '123456',
}
}
ps:键必须都是大写2.告诉django用pymysql替换它默认mysqldb模块连接数据库
方式1:在你的项目文件夹下面的__init__.py
方式2:也可以在你的应用文件夹下面的__init__.py
写入一下两行:
# 固定写法
import pymysql
pymysql.install_as_MySQLdb() # 告诉django用pymysql代替mysqldb连接数据库六、ORM
1、ORM简介
ORM 全拼Object-Relation Mapping. 对象关系映射; 类 》》》 表 对象 》》》 表记录 对象的属性 》》》 一条记录某个字段对应的值 django的orm不能够自动创建库,但是可以自动帮你创建表 提示:一个django项目就使用一个库,不要多个django项目使用一个库
2、ORM优缺点
优点:
(1)只需要面向对象编程, 不需要面向数据库编写代码.
对数据库的操作都转化成对类属性和方法的操作.
不用编写各种数据库的sql语句.
(2)实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.
不在关注用的是mysql、oracle...等.
通过简单的配置就可以轻松更换数据库, 而不需要修改代码.
缺点:
相比较直接使用SQL语句操作数据库,有性能损失.
根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失.2、数据库同步
##models.py## 当models.py文件有改动时,就要在项目目录中执行下列两个命令; python3 manage.py makemigrations 将你的数据库变动记录到一个小本本上(并不会帮你创建表) python3 manage.py migrate 将你的数据库变动正在同步到数据库中
七、ORM使用
1、字段类型
示例:
class User(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
password = models.CharField(max_length=16)
addr = models.CharField(max_length=32, default='China')
属性名 = models.字段类型,定义属性时需要指定字段类型, 通过字段类型的参数指定选项
属性名:
不允许使用python的保留关键字
不允许使用mysql的保留关键字
不允许使用连续的下划线,因为Django的查询语法就是连续的下划线
AutoField:自动增长的IntegerField, 不指定时Django会自动创建属性名为id的自动增长属性
BooleanField:布尔字段,值为True或False
NullBooleanField:支持Null、True、False三种值
CharField(max_length=20):字符串
参数max_length表示最大字符个数
TextFiled:大文本字段,一般超过4000个字符时使用
IntegerField:整数
DecimalField(max_digits=None, decimal_places=None):可以指定精度的十进制浮点数
参数max_digits表示总位数
参数decimal_places表示小数位数
FloatField():浮点数 DateField[auto_now=False, auto_now_add=False]):日期
参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false
参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
TimeField:参数和DateField一样
DateTimeField:日期时间,参数同DateField
FileField:上传文件字段,以二进制的形式
ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片2、字段选项
null:如果为True,表示允许为空,默认值是False
blank:如果为True,则该字段允许为空白,默认值是False 对比:null是数据库范畴的概念,blank是表单验证范畴的
db_column:字段的名称,如果未指定,则使用属性的名称(只限于数据库表中的名字,操作数据库还是类属性的名字)
db_index:若值为True, 则在表中会为此字段创建索引,默认值是False(为了优化查询速度 )
default:默认值,这可以是值或可调用对象。如果可调用,则每次创建新对象时都会调用它。
primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
unique:如果为True, 这个字段在表中必须有唯一值,这个值不能重复,默认值是False
关系型字段类型:关联表中使用:
注意:Django会自动为表创建主键字段
如果使用选项设置某属性为主键字段后,Django不会再创建自动增长的主键字段
默认创建的主键字段为id,可以使用pk代替,pk全拼为primary key3、关系字段类型
关系型数据库的关系包括三种类型:
ForeignKey:一对多,将字段定义在多的一端中
ManyToManyField:多对多,将字段定义在任意一端中
OneToOneField:一对一,将字段定义在任意一端中
可以维护递归的关联关系,使用self指定4、元选项
作用:修改数据库表的默认的名称
数据库表的默认名称为 :
应用名_模型名
如:应用名:app01 模型类:User
则表名为:app01_user
class BookInfo(models.Model):
name = models.CharField(max_length=20) #图书名称
class Meta: #元信息类
db_table = 'bookinfo' #自定义表的名字八、Django数据库的操作
from django.shortcuts import render,HttpResponse,redirect
import pymysql
from app01 import models
# Create your views here.
def login(request):
# 获取用户端提交的请求方式
print(request.method) # 拿到的请求方式是全大写的字符串
# if request.method == 'GET':
# return render(request,'login.html')
# elif request.method == 'POST':
# return HttpResponse("收到了 老弟")
if request.method == 'POST':
# print(request.POST) # 你就把它当成一个大字典里面存放了客户端post提交的所有的数据
# # request.POST:< QueryDict: {'username': ['jason'], 'password': ['123']} >
# print(request.POST.get('username')) # value虽然是个列表但是获取value的时候拿到却是单个元素
# # 默认只会取value列表里面的最后一个元素
# print(request.POST.getlist('username')) # 要想一次性获取value列表里面所有的数据需要用getlist()
# print(request.POST['password']) # 不推荐使用该方法获取数据
# 获取用户输入的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
conn = pymysql.connect(
host='127.0.0.1',
port = 3306,
user = 'root',
password = '123',
database = 'day54',
charset = 'utf8',
autocommit = True
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from userinfo where name=%s and password=%s',(username,password))
user_info = cursor.fetchall()
if user_info:
return HttpResponse('登录成功')
# print(request.GET) # <QueryDict: {'username': ['jason'], 'password': ['123']}>
# # 获取get请求数据的方式跟post请求完全一样!!!
return render(request,'login.html')
def reg(request):
if request.method == 'POST':
# 获取用户输入的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# 操作数据库user表插入数据
# 方式1:
# user_obj = models.User.objects.create(name=username,password=password)
# 方式2:
user_obj = models.User(name=username,password=password)
user_obj.save() # 对象调用save方法保存到数据库
print(user_obj.pk) # pk获取主键字段对应的值 无论的你主键叫什么名字
print(user_obj.name) # 获取用户数据的name值
print(user_obj.password) # 获取用户数据的password值
return redirect('/userlist/')
return render(request,'reg.html')
def userlist(request):
# 获取数据库数据
user_list = models.User.objects.all() # select id,name,password form user;
# print(user_list.query) # 只要是QuerySet就可以点query查看获取到当前QuerySet对象的内部sql语句
# for user_obj in user_list:
# print(user_obj.pk,user_obj.name)
return render(request,'userlist.html',locals())
def delete_user(request):
# 从get请求携带的参数中获取用户想要删除的数据id
delete_id = request.GET.get('delete_id')
# res = models.User.objects.filter(id=1)[0]
# res = models.User.objects.filter(id=1).first()
models.User.objects.filter(id=delete_id).delete() # 会将queryset所有的数据对象全部删除
# print(res) # <QuerySet [<User: jason>]>
# # print(res.query)
# print(type(res))
return redirect('/userlist')
def edit(request):
if request.method == 'POST':
print(request.POST)
print(request.GET)
username = request.POST.get('username')
password = request.POST.get('password')
# 获取编辑对象的id方式
edit_id = request.POST.get('edit_id')
edit_id = request.GET.get('edit_id')
# 更新数据库
models.User.objects.filter(id=edit_id).update(name=username,password=password)
return redirect('/userlist')
# 获取用户想要修改的数据的id
edit_id = request.GET.get('edit_id')
# 将该数据查询出来渲染到一个编辑页面
# 查询数据方式1
user_obj = models.User.objects.filter(id=edit_id).first()
# 查询数据方式2
# # user_obj = models.User.objects.get(id=edit_id)
# print(user_obj,type(user_obj))
# 将当前数据渲染到一个编辑页面上
return render(request,'edit.html',locals())九、a标签href属性
利用a标签href属性 可以指定页面跳转的路径 href可以写全路径 但是推荐写后缀即可:
<a href="/reg/" class="btn btn-success">添加数据</a>
<a href="/edit/?edit_id={{ user_obj.pk }}" class="btn btn-primary">编辑</a>
<a href="/delete_user/?delete_id={{ user_obj.pk }}" class="btn btn-danger">删除</a>
# 注意 路径的书写一定要加斜杠十、表单元素input type=”hidden”
隐藏域在页面中对于用户是不可见的,在表单插入中隐藏域的目的在于收集和发送信息,以利于被处理表单的程序所使用
注:隐藏只是在网页页面上不显示输入框,但是虽然隐藏了,还是具有form传值功能。一般用来传值,而不必让用户看到。
基本语法:
<input type="hidden" name="field_name" value="value" />
<div class="container">
<div class="row">
<h1>编辑数据</h1>
<div class="col-md-6 col-md-offset-3">
<form action="/edit/?edit_id={{ user_obj.pk }}" method="post">
<input type="hidden" name="edit_id" value="{{ user_obj.pk }}">
<p>username:<input type="text" name="username" value="{{ user_obj.name }}" class="form-control"></p>
<p>password:<input type="text" name="password" value="{{ user_obj.password }}" class="form-control"></p>
<input type="submit" class="btn btn-warning">
</form>
</div>
</div>
</div>
def edit(request):
if request.method == 'POST':
print(request.POST)
print(request.GET)
username = request.POST.get('username')
password = request.POST.get('password')
# 获取编辑对象的id方式
edit_id = request.POST.get('edit_id')
edit_id = request.GET.get('edit_id')
# 更新数据库
models.User.objects.filter(id=edit_id).update(name=username,password=password)
return redirect('/userlist')
# 获取用户想要修改的数据的id
edit_id = request.GET.get('edit_id')
# 将该数据查询出来渲染到一个编辑页面
# 查询数据方式1
user_obj = models.User.objects.filter(id=edit_id).first()
# 查询数据方式2
# # user_obj = models.User.objects.get(id=edit_id)
# print(user_obj,type(user_obj))
# 将当前数据渲染到一个编辑页面上
return render(request,'edit.html',locals())