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_ ...
随机推荐
- Pyecharts-数据可视化模块
Pyecharts 介绍 数据可视化模块 Echarts是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可.而Python是一门富有表达力的语言,很适合用于数据处 ...
- Parity game POJ - 1733 带权并查集
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; <& ...
- MySql 小表驱动大表
在了解之前要先了解对应语法 in 与 exist. IN: select * from A where A.id in (select B.id from B) in后的括号的表达式结果要求之输出一列 ...
- thinkphp3.2短信群发项目实例
项目功能是企业给客户群发短信,我就写这么多,也不知道你能不能运行成功,如果有问题可以在QQ上问我:605114821 项目文件SMS_V2.zip下载地址,百度云:http://yun.baidu.c ...
- Electron+React+七牛云 实战跨平台桌面应用(最新更新)
课程资料获取链接:点击这里 前市场上对 Electron 的呼声很高,它几乎是 Web 开发人员开发桌面客户端的唯一途径,很多大厂都使用 Electron 开发自己的原生应用.Electron 天生适 ...
- vue keep-alive 遇见 vue-router
keep-alive 遇见 vue-router ·keep-alive 是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 ·routre-view也是一个组件,如果直接被包在kee ...
- (1)-Android学习笔记之:初识Android系统架构和项目结构
Android系统架构 Android程序结构 创建一个Android项目,为初学便于理解,将程序项目结构切换为Project模式,项目结构如下 .gradle和.idea:这两个目录下放的都是And ...
- 541-反转字符串 II
541-反转字符串 II 给定一个字符串和一个整数 k,你需要对从字符串开头算起的每个 2k 个字符的前k个字符进行反转.如果剩余少于 k 个字符,则将剩余的所有全部反转.如果有小于 2k 但大于或等 ...
- sqlalchemy_mptt一次调优
问题背景: 我用sqlalchemy_mptt构建了一个多级分类项目,数据库用了sqlite.随着数据条数越来越多,写入速度逐渐变慢,一棵树的插入甚至需要1分钟,远远不能满足需求 分析思路: 1. 批 ...
- 快速搭建一个基于react的项目
最近在学习react,快速搭建一个基于react的项目 1.创建一个放项目文件夹,用编辑器打开 2.打开集成终端输入命令: npm install -g create-react-app 3. cre ...