Django之orm
Posted weiyiming007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之orm相关的知识,希望对你有一定的参考价值。
一、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 key
3、关系字段类型
关系型数据库的关系包括三种类型:
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())
以上是关于Django之orm的主要内容,如果未能解决你的问题,请参考以下文章