准备工作:

  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表单操作的更多相关文章

  1. Django 的ORM 表间操作

    Django之ORM表间操作   之前完成了简单的数据库数据增加操作.这次学习更多的表间操作. 单表操作 增加 方式一 b = Book(title="Python基础", pub ...

  2. Django之form表单操作

    小白必会三板斧 from django.shortcuts import render,HttpResponse,redirect HttpRespone:返回字符串 render:返回html页面 ...

  3. 基于JQuery的前端form表单操作

    Jquery的前端表单操作:     jquery提供了良好的方法封装,在一些基本的操作的时候,能节省很多的麻烦,其中,在具体使用时,form表单的数据提交是最频繁也最常见的前后数据交换方式,所以在前 ...

  4. 【JavaScript】DOM之表单操作

    DOM 表单操作 1.获取表单 获取表单元素 以Document对象中forms属性来获取当前HTML页面所有表单集合以Document对象中表单的name属性值来获取表单元元素 <body&g ...

  5. python -使用Requests库完成Post表单操作

    """ 使用Requests库完成Post表单操作 """ #_*_codingn:utf8 _*_ import requests fro ...

  6. Django之mysql表单操作

    在Django之ORM模型中总结过django下mysql表的创建操作,接下来总结mysql表记录操作,包括表记录的增.删.改.查. 1. 添加表记录 class UserInfo(models.Mo ...

  7. ExtJs 第二章,Ext.form.Basic表单操作

    1.认识Ext.form.Panel表单面板         Ext.form.field.CheckBox 复选框 checkboxfield Ext.form.CheckBoxGroup 复选框组 ...

  8. 关于form与表单操作

    form表单自动提交规则 form表单中只有一个type=text的input,在input中按enter键,会自动提交: form表单中有多个type=text的input,且无type=submi ...

  9. 还没被玩坏的robobrowser(7)——表单操作

    背景 有一些站点是需要登录之后才能抓取内容的,另外做web测试的时候登录是家常便饭. 这一节里我们就以登陆testerhome为例,讲解一下robobrowser中form的操作. 预备知识 get_ ...

随机推荐

  1. iframe在iphone手机上的问题

    问题1: 通过document.addEventListener("scroll",function(){})对页面滚动监听事件进行监听,但ios下$(document).scro ...

  2. 高数(求x的n次方的导数)

  3. Cloud开发动态列的简单账表

    业务场景:客户需要根据过滤条件的不同显示不同的列.如下方式可以实现动态的列名. using System;using System.Collections.Generic;using System.L ...

  4. 5.Docker Compose 部署 Harbor

    什么是 Harbor Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器,通过添加一些企业必需的功能特性,例如安全.标识和管理等,扩展了开源 Docker Dis ...

  5. Selenium3+python自动化016-多线程

    1.进程 什么是进程? 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基 ...

  6. 自定义Redux

    实现mini版redux 1. 理解redux模块 1). redux模块整体是一个对象模块 2). 内部包含几个函数 createStore(reducers) // reducers: funct ...

  7. [CF1034A] Two Rabbits - 数学

    判断能否整除即可 #include <bits/stdc++.h> using namespace std; int x,y,a,b; int main() { int t; ios::s ...

  8. phpstorm对比代码

    方法一 首先在phpstorm中左侧的资源管理器中,按住键盘上的CTRL键选中两个文件,然后鼠标右键,点击菜单中的"Compare Tow Files",就可以了,如下图 方法二 ...

  9. spring项目启动报错

    个人博客 地址:http://www.wenhaofan.com/article/20180921134534 错误信息 ERROR [localhost-startStop-1] - Context ...

  10. NOI2005 维护数列 lg2042

    这道题据说是noi题目中算是比较毒瘤的数据结构题了,5k多的代码加上随手写挂细节,我调了两天 题面见https://www.luogu.org/problemnew/show/P2042 (歪个题,这 ...