ORM表单操作
准备工作:
1、在orm操作表单之前需要先修改下django中连接的数据库,默认连接的是SQLit3,这里我们修改成mysql
2、mysql使用的版本是5.6,已经安装好了,直接连接就可以使用
创建django项目,这里我创建的django使用的是pycharm创建的,其中应用、模板都已经创建好了,不需要我们手动去创建了,因为要连接到mysql数据库,默认不支持mysql连接,我们还需要做一些修改。
创建需要用到的数据库库文件:
库名:book_system
修改django中配置文件settings.py文件:
在项目中或者应用中目录的__init__.py文件中添加
import pymysql
pymysql.install_as_MySQLdb()
到这里初步的设置算是完成了,因为我们要使用orm操作数据库,还需要先设计表格字段类型
在创建的应用app中的models.py目录中创建类
class User(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField()
# DateField 年月日;DateTimeField 年月日时分秒
register_time=models.DateField()
def __str__(self):
return '对象的名字是:%s'%self.name
# 设计book表
class Book(models.Model):
# 设置title字段为varchar类型
title=models.CharField(max_length=32)
# max_digists设置数字长度最大为8,decimal_places小数位
price=models.DecimalField(max_digits=8,decimal_places=2)
# DateField 年月日;DateTimeField 年月日时分秒;auto_now:每次操作改数据都会自动更新时间;auto_now_add:新增数据的时候会将当前时间自动添加,后续的修改该字段不会自动更新
publish_date=models.DateField(auto_now_add=True)
# 外键关系
publish=models.ForeignKey(to='Publish')
authors=models.ManyToManyField(to='Author') def __str__(self):
return '书籍对象的名字是:%s'%self.title # 设计出版社表
class Publish(models.Model):
name=models.CharField(max_length=32)
addr=models.CharField(max_length=32)
#这里默认EmailField类型在不加载其它模块的情况下就是char类型
email=models.EmailField()
def __str__(self):
return '出版社对象的名字:%s'%self.name
# 设计作者表格
class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField() authordetail=models.OneToOneField(to='AuthorDetail')
def __str__(self):
return '作者对象的名字:%s'%self.name #作者表的扩展表
class AuthorDetail(models.Model):
phone=models.CharField(max_length=32)
addr=models.CharField(max_length=32)
执行数据库迁移命令、生成数据库需要的表
python3 manage.py makemigrations 将数据库更改记录添加到小本本上(对应应用下migrations文件夹)
python3 manage.py migrate 将更改同步到数据库(真正的操作数据库)
执行完成后查看数据:
有一些是我们自己设计的,有些是orm系统自己需要用到的表
注意:数据库创建好了,单独的py文件测试orm操作会报错,需要配置参
导入app应用中的models模块
- 一、数据操作从创建、删除、修改、查询这四个方面开始
新增数据的两种方式:
新增数据方式1:(基于create方法创建)
#新增数据,创建表
user_obj=models.User.objects.create(name='jason',age='',register_time='2019-06-12')
print(user_obj.register_time)
新增数据方式2:(基于对象绑定的方法创建)
from django.test import TestCase # Create your tests here.
import os
import sys
import datetime if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test01.settings")
import django
django.setup()
from app01 import models
#新增数据,创建表
# user_obj=models.User.objects.create(name='jason',age='25',register_time='2019-06-12')
# print(user_obj.register_time) user_obj=models.User(name='tank',age='23',register_time=datetime.datetime.now())
user_obj.save()
删除数据的两种方式
# 方式1
res = models.User.objects.filter(name='tank').delete()
print(res) #删除数据会有返回值
# 方式2
res = models.User.objects.filter(name='jason').first()
res.delete() #删除数据没有返回值
修改数据两种方式
# 方式1
models.User.objects.filter(name='tank').update(age='18')
# 方式2
res=models.User.objects.filter(name='tank').first()
res.age=20
res.save()
查询数据
<1> all(): 查询所有结果 res=models.User.objects.all()
print(res) <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
res = models.User.objects.filter(name='tank',age=21)
print(res) #filter内支持多个参数,查询条件只有同时满足才会返回查询结果 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象 <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
res =models.User.objects.exclude(name='tank')
print(res) #查询返回exclude条件之外的其它数据,通俗点就是取反 <5> order_by(*field): 对查询结果排序('-id')/('price')
res=models.User.objects.order_by('name')
print(res) #order_by内可以不同的字段
res=models.User.objects.order_by('-name')
print(res) #倒叙,效果和reverse一样
<6> reverse(): 对查询结果反向排序 >>>前面要先有排序才能反向 <7> count(): 返回数据库中匹配查询(QuerySet)的对象数量。
res=models.User.objects.count()
print(res)
<8> first(): 返回第一条记录
res=models.User.objects.all().first()
print(res)
<9> last(): 返回最后一条记录
res=models.User.objects.all().last()
print(res)
<10> exists(): 如果QuerySet包含数据,就返回True,否则返回False
res=models.User.objects.filter(name='test').exists()
print(res) #判断数据是否存在,存放返回true,不存在返回false
<11> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 <12> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <13> distinct(): 从返回结果中剔除重复纪录
基于双下划线的查询
res=models.User.objects.filter(age__gt=21)
print(res) # 查询年龄大于21岁
res=models.User.objects.filter(age__lt=21)
print(res) # 查询年龄小于21岁
age__gte #大于等于
age__lte #小于等于
age__in=[44,22,73] #年龄是44或22或73,只要有一个满足就返回数据
age__range=[22,44] #年龄在22——44之间范围内
register_time__year=2019 #register_time这个字段的日期数据中年份是2019的数据打印出来
res=models.User.objects.filter(name__contains='o')
print(res) #name字段中包含有o字符的值打印出来
name__icontains='E' #含有E字符的值都打印出来,不区分大小写
name__startswith='t' #字段中符合指定字符开头的打印出来
name__endswith='n' #字段中负责指定字符结尾的打印出来
到此单表查询结束
================================================================= 多表查询 插入数据
models.Book.objects.create(title='红楼梦',price='66.66',publish_id=1)
传输数据对象:
publish_obj=models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='三国演义',price=199.99,publish=publish_obj)
修改数据
models.Book.objects.filter(pk=1).update(publish_id=3)
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)
对象修改
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish_id = 3 # 点表中真实存在的字段名
book_obj.save() publish_obj = models.Publish.objects.filter(pk=2).first()
book_obj.publish = publish_obj # 点orm中字段名 传该字段对应的表的数据对象
book_obj.save()
删除数据
models.Book.objects.filter(pk=1).delete()
models.Publish.objects.filter(pk=1).delete()
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.delete()
多表之间添加关系(数据)
方法1
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.add(1)
方法2
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=3).first()
book_obj.authors.add(author_obj,author_obj1)
修改表关系使用set(),set传递的必须是可迭代对象
方法1
book_obj = models.Book.objects.filter(pk=3).first()
可以传数字和对象,并且支持传多个
book_obj.authors.set((1,))
book_obj.authors.set((1,2,3)) 方法2
author_list = models.Author.objects.all()
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.set(author_list)
删除书籍与作者的绑定关系
方法1
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.remove(1) 方法2
book_obj = models.Book.objects.filter(pk=3).first()
author_list = models.Author.objects.all()
book_obj.authors.remove(*author_list) # 需要将queryset打散
清空关系表中的数据clear() 清空的是你当前这个表记录对应的绑定关系
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.authors.clear() 基于对象的表查询
正向
查询书籍是三国演义出版社的邮箱
book_obj =models.Book.objects.filter(title='三国演义').first()
print(book_obj.publish.email)
查询书籍是三国演义的作者的姓名
book_obj=models.Book.objects.filter(title='三国演义').first()
print(book_obj.authors) # app01.Author.None出现这种情况是打印出的数据不是的单个是多个
print(book_obj.authors.all())
查询作者为‘大猫’的电话号码
phone_obj=models.Author.objects.filter(name='大猫').first()
print(phone_obj.authordetail.phone) 反向
查询出版社是上海出版社出版的书籍 一对多字段反向查询
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set) # app01.Book.None
print(publish_obj.book_set.all())
查询作者jason写过的所有的书 多对多字段的反向查询
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set) # app01.Book.None
print(author_obj.book_set.all()) 查询作者电话号码是110的作者姓名 一对一字段的反向查询
authordetail_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(authordetail_obj.author.name)
基于双下滑线的查询
正向
查询书籍为三国演义的出版社地址
res = models.Book.objects.filter(title='三国演义').values('publish__addr','title')
print(res)
查询书籍为xxx的作者的姓名
res = models.Book.objects.filter(title='xxx').values("authors__name",'title')
print(res)
查询作者为jason的家乡
res = models.Author.objects.filter(name='jason').values('authordetail__addr')
print(res)
反向
查询南方出版社出版的书名
res = models.Publish.objects.filter(name='南方出版社').values('book__title')
print(res)
查询电话号码为120的作者姓名
res = models.AuthorDetail.objects.filter(phone=120).values('author__name')
print(res)
查询作者为jason的写的书的名字
res = models.Author.objects.filter(name='jason').values('book__title')
print(res)
查询书籍为三国演义的作者的电话号码
res = models.Book.objects.filter(title='三国演义').values('authors__authordetail__phone')
print(res)
聚合查询 aggregate
from django.db.models import Max,Min,Count,Sum,Avg
查询所有书籍的作者个数
res = models.Book.objects.filter(pk=3).aggregate(count_num=Count('authors'))
print(res)
查询所有出版社出版的书的平均价格
res = models.Publish.objects.aggregate(avg_price=Avg('book__price'))
print(res) # 4498.636
统计东方出版社出版的书籍的个数
res = models.Publish.objects.filter(name='东方出版社').aggregate(count_num=Count('book__id'))
print(res) 分组查询(group_by) annotate
统计每个出版社出版的书的平均价格
res = models.Publish.objects.annotate(avg_price=Avg('book__price')).values('name','avg_price')
print(res)
统计每一本书的作者个数
res = models.Book.objects.annotate(count_num=Count('authors')).values('title','count_num')
print(res)
统计出每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
print(res)
查询每个作者出的书的总价格
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
print(res)
ORM表单操作的更多相关文章
- Django 的ORM 表间操作
Django之ORM表间操作 之前完成了简单的数据库数据增加操作.这次学习更多的表间操作. 单表操作 增加 方式一 b = Book(title="Python基础", pub ...
- Django之form表单操作
小白必会三板斧 from django.shortcuts import render,HttpResponse,redirect HttpRespone:返回字符串 render:返回html页面 ...
- 基于JQuery的前端form表单操作
Jquery的前端表单操作: jquery提供了良好的方法封装,在一些基本的操作的时候,能节省很多的麻烦,其中,在具体使用时,form表单的数据提交是最频繁也最常见的前后数据交换方式,所以在前 ...
- 【JavaScript】DOM之表单操作
DOM 表单操作 1.获取表单 获取表单元素 以Document对象中forms属性来获取当前HTML页面所有表单集合以Document对象中表单的name属性值来获取表单元元素 <body&g ...
- python -使用Requests库完成Post表单操作
""" 使用Requests库完成Post表单操作 """ #_*_codingn:utf8 _*_ import requests fro ...
- Django之mysql表单操作
在Django之ORM模型中总结过django下mysql表的创建操作,接下来总结mysql表记录操作,包括表记录的增.删.改.查. 1. 添加表记录 class UserInfo(models.Mo ...
- ExtJs 第二章,Ext.form.Basic表单操作
1.认识Ext.form.Panel表单面板 Ext.form.field.CheckBox 复选框 checkboxfield Ext.form.CheckBoxGroup 复选框组 ...
- 关于form与表单操作
form表单自动提交规则 form表单中只有一个type=text的input,在input中按enter键,会自动提交: form表单中有多个type=text的input,且无type=submi ...
- 还没被玩坏的robobrowser(7)——表单操作
背景 有一些站点是需要登录之后才能抓取内容的,另外做web测试的时候登录是家常便饭. 这一节里我们就以登陆testerhome为例,讲解一下robobrowser中form的操作. 预备知识 get_ ...
随机推荐
- 关于新版vue-cli安装json-server在build文件里没生成出dev-server文件
今天在安装json-server时遇到一个问题,build文件里并没有生成dev-server.js文件, 开始是怀疑配置有问题,或者安装不正确,然后重新安装了两三次,还是这样,郁闷.. 通过查询资料 ...
- Fabric智能合约(base)
这里的智能合约仅包含Init函数和Invoke函数. 为什么一定是这两个方法? 因为在源码中的智能合约模块有这样的接口,如果要完成智能合约的相关编程,就需要实现源码中定义的接口,接口中定义了这两个方法 ...
- Yarn报错:Exception message: /bin/bash: line 0: fg: no job control
Exception message: /bin/bash: line 0: fg: no job control 这个错误是 本地idea跨平台远程调试hadoop集群出现的,在使用windows调用 ...
- windows命令提示符常用命令
1.进入某个磁盘 c: 进入c盘 d: 进入d盘 2.返回到根目录 cd \ 3.查看当钱路径下的文件和文件夹 dir 4.清空窗口内容 cls 5.关闭窗口 exit 6.返回上一级目录 cd . ...
- The Way to Home CodeForces - 910A
4个月前做的一道题,当时不知道为什么,写了一个bfs,直接就超时了. 现在再看这个题目,发现就是一个简单的贪心,每次走最远即可. #include <bits/stdc++.h> usin ...
- vue常用插件之图片预览
v-viewer(1.4.2) 非常实用的图片预览插件,支持旋转.缩放.翻转等操作 一.npm安装 npm i v-viewer -S 二.全局引入(main.js中) import 'viewerj ...
- cURL error 60: SSL certificate problem: unable to get local issuer certificate 解决方法
微信开发的时,请求接口报错如下: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see ...
- Java_Day4(上)
Java learning_Day3(上) 本人学习视频用的是马士兵的,也在这里献上 <链接:https://pan.baidu.com/s/1qKNGJNh0GgvlJnitTJGqgA> ...
- 理解LDAP与LDAP注入
0x01 LDAP简介 LDAP,轻量目录访问协议 |dn :一条记录的位置||dc :一条记录所属区域||ou :一条记录所属组织||cn/uid:一条记录的名字/ID| 此处我更喜欢把LDAP和 ...
- APP和web设计区别
1.web在给定了核心功能后,还可以往页面再添加小需求如banner.快捷工具条.分页等. APP界面设计时,则偏向精简,尽可能明显的展示核心功能. 2.APP中需要考虑ISO和Andriod两种交互 ...