ORM的相关操作

ORM的概念

ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。ORM在业务逻辑层和数据库层之间充当了桥梁的作用。ORM的优势:ORM解决的主要问题是对象和关系的映射ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。ORM的劣势:在一定程度上牺牲程序的执行效率。

在Django中格式使用ORM连接Mysql

‘‘‘
1. 手动创建数据库
2. 在settings.py里面配置一下数据库的连接信息(告诉Django连接哪一个数据库)
    DATABASES = {
        ‘default‘: {
            ‘ENGINE‘: ‘django.db.backends.mysql‘,  # 连接数据库的类型
            ‘NAME‘: ‘day62xiawu‘,  # 数据库名字
            ‘HOST‘: ‘127.0.0.1‘,  # IP
            ‘PORT‘: 3306,  # 端口
            ‘USER‘: ‘root‘,  # 用户名
            ‘PASSWORD‘: ‘123456‘,  # 密码
        }
    }
3. 在和settings.py同目录下的__init__.py文件中,告诉Django用pymysql代替MySQLdb来连接数据库
    import pymysql
    pymysql.install_as_MySQLdb()
4. 在app/models.py中,定义类,类一定要继承models.Model
    class Book(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
5. 执行两条命令
    1. 在哪儿执行?
        在项目的根目录(有manage.py文件的那个目录)
    2. 命令
        python manage.py makemigrations   --> 将models.py文件中的改动记录在小本本(app/migrations/00xx_****.py)上

        python manage.py migrate           --> 将改动翻
‘‘‘

常用字段

‘‘‘
1.AutoField
int自增列,必须填入参数 primary_key=True 没有自增列,则自动会创建一个列名为id的列。
因此在创建表的时候id不写,也能创建成功,默认创建一个id字段
id=models.AutoField(primary_key=True)
2.IntegerField(10位的长度)
整数类型,范围在 -2147483648 to 2147483647。
使用IntegerField类型不能存手机号,手机号是11位。用来存age
 BigIntegerField(19位)可以用来存手机号
age=models.IntegerField()
3.CharField:表示varchar
字符类型,必须提供max_length参数, max_length表示字符长度。
name=models.CharField(max_length=255)
4.DecimalField 10进制小数
        参数:max_digits,小数总长度
            decimal_places,小数位长度
5.自定义char类型字段:
class FixedCharField(models.Field):
    """
    自定义的char类型的字段类
    """
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs)

    def db_type(self, connection):
        """
        限定生成数据库表的字段类型为char,长度为max_length指定的值
        """
        return ‘char(%s)‘ % self.max_length
class Class(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=25)
    # 使用自定义的char类型的字段
    cname = FixedCharField(max_length=25)
6.DateField 日期字段,日期格式  YYYY-MM-DD 相当于Python中的datetime.date()实例
DateTimeField 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]  相当于Python中的datetime.datetime()
DateField和DateTimeField有两个属性:
1. auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。相当于人的生日
2.auto_now=True,每次更新数据记录的时候会更新该字段
不能同时用,一般都设置auto_now_add=True
birthdy=models.DateField(auto_now_add=True)
在表中添加数据时需要手动添加birthday 在create创建时,不用添加birthday,会自动添加
7.datetime.timedelta类型
求失效的时间
import datetime
now=datetime.datetime.now()
print(now)
#有效其七天
d7=datetime.timedelta(days=7) #也可以weeks,不能years 一年52周
ret=now+d7
print(ret)
‘‘‘

字段参数

1.null:用于表示某个字段可以为空用于表示某个字段可以为空2.unique:如果设置为unique=True 则该字段在此表中必须是唯一的。如身份证号,手机号都要设置唯一的3.db_index:如果db_index=True 则代表着为此字段设置索引4.default

关系字段

ForeignKey

外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 ‘一对多‘中‘多‘的一方
字段参数:
1.to:设置要关联的表
2to_field 设置要关联的表的字段
3.related_name:用于代替原反向查询时的‘表名_set。即关系表中少的一方要查询多的一方时
一个班级中有多个学生,学生是多的一方
class Classes(models.Model):
    name = models.CharField(max_length=32)
class Student(models.Model):
    name = models.CharField(max_length=32)
    the_class = models.ForeignKey(to="Classes")
正向查询:book_obj=models.Classes.objects.filter(pk=1).first()
print(book_obj.publish.name)
反向查询:表名_set 查询某个班级关联的所有学生:models.Classes.objects.first().student_set.all()
在ForeignKey字段中添加了参数 related_name 后
 the_class = models.ForeignKey(to="Classes", related_name="students")
 models.Classes.objects.first().students.all()
4.on_delete
当删除关联表中的数据时,当前表与其关联的行的行为
models.CASCADE
删除关联数据,与之关联也删除
 publisher = models.ForeignKey(to="Publisher",on_delete=models.CASCADE)
models.SET_NULL
删除关联数据,与之关联的值设置为null
models.SET_DEFAULT
删除关联数据,与之关联的值设置为默认值
models.SET
删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
 publisher = models.ForeignKey(to="Publisher",on_delete=models.SET(10)

OneToOneField

通常一对一字段用来扩展已有字段。把常用的字段放在一张表中,不常用的字段放到另一张表中比如作者姓名和名字经常用到,而年龄和地址不经常用到,就到年龄和地址放到另一张表中
class Person(models.Model):
    id=models.AutoField(primary_key=True)
    name=models.CharField(max_length=255)
    detail=models.OneToOneField(to="PersonDetail")
class PersonDetail(models.Model):
    age=models.IntegerField()
    addr=models.TextField()
正向查询:
egon=models.Person.objects.filter(name="egon").first()
print(egon.detail.age)
反向查询:
authorDetail_list=models.PersonDetail.objects.filter(addr="beijing")
for obj in authorDetail_list:
     print(obj.person.name)

ManyToManyField

用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系1.自己关联自己的表 朋友的信息也存在Person这张表中。关联的话仍关联Person这张表。用于评论功能
class Person(models.Model):
    name = models.CharField(max_length=16)
    friends = models.ManyToManyField("self")
2.symmetrical仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True。不能进行反向查询。可以使用person_set属性进行反向查询 db_table可自定义第三张表的表名
class Person(models.Model):
    name = models.CharField(max_length=16)
    friends = models.ManyToManyField("self", symmetrical=False db_table="表名"
3.在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系在不需要额外的字段时,用自动生成的第三张表即可。如果需要额外的字段,就自己动创建第三张表。此时就需要通过through来指定第三张表的表名

###约会网站 记录约会时间##
###约会记录##
# 男孩1 女孩1
# 男孩2 女孩2
# 男孩3 女孩3
class Boy(models.Model):
    name=models.CharField(max_length=32)
    def __str__(self):
         return self.name
class Girl(models.Model):
    name=models.CharField(max_length=32)
    #through_fields("field1","field2") 多对多建在建在哪张表,field1就是这个表的名字 field2是目标表的名字
    boys=models.ManyToManyField(to=Boy,through="Info",through_fields=("girl","boy"))  #顺序不能颠倒
    def __str__(self):
         return self.name
class Info(models.Model):
    boy=models.ForeignKey(to=Boy)
    girl= models.ForeignKey(to=Girl)
    date=models.DateField(auto_now_add=True)

class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=16, null=False, unique=True)
    # 告诉ORM 我这张表和book表是多对多的关联关系,ORM自动帮我生成了第三张表
    book = models.ManyToManyField(to="Book" related_name="books" )
正向查询:
book_obj=Book.objects.filter(title="后来的我们").first()
authors=book_obj.authors.all()
for author_obj in authors:
     print(author_obj.name,author_obj.authorDetail.telephone)
反向查询:
author_obj=Author.objects.get(name="egon")
book_list=author_obj.book_set.all()        #与egon作者相关的所有书籍
book_list=author_obj.books.all() 添加related_name="books"
for book_obj in book_list:
    print(book_obj.title)

增 删 改 查操

增 删 改 查的操作均在views.py中操作编辑完要保存以出版设为例:1.单表的操作:
增 models.Publisher.objects.create(name="天青烟雨出版社")
 删 models.Publisher.objects.get(id=1).delete()
 改 obj=models.Publisher.object.get(id=1) #通过get得到一个对象。在表中可以理解为得到一行表中的内容
    obj.name=new_name
    obj.save()
 查 obj=models.Publisher.objects.get(id=1)
2.外键的增删改查:增,删,查和单表一样
改:book_obj=models.Book.objects.get(id)
    book_obj.name 是书的名字。是一个属性
    book_obj.publisher 是和书关联的出版社id值,是书的一个自身属性
    book_obj.publisher 是和书关联的出版社对象。是一个对象
    book_obj.publisher.id 出版社的id
    book_obj.publisher.name  出版社的名字
3.多对多的操作
1.查询id为1的作者写哪些书
author_obj=models.Author.objects.get(id=1)
author_obj.books.all() 和作者关联的所有书对象(这些对象包括书的id,书名等信息)
2.增加
在为书籍添加作者的时候,书籍已经创建。新建作者,然后显示出书籍列表,为其选择
在处理函数时,获取作者或关联的书籍,书籍是多选的不能用get获取
author=request.POST.get("author")
# 书籍选择是多选的,不能用get,使用getlist
books = request.POST.getlist("book")
# 创建作者
new_author_obj = models.Author.objects.create(name=author)
# 把新作者和书籍建立对应关系,自动提交
new_author_obj.book.set(books)
author_obj.books.set([1,2,3]) 把id是1、2、3的书和我这个作者关联上
3.编辑时,修改完书籍直接使用set赋新值
book_id = request.POST.getlist("books")
        author_obj=models.Author.objects.get(id=author_id)author_obj.name=author_name
        author_obj.book.set(book_id)
        author_obj.save()

元信息

1.ORM对应的类里面包含另一个Meta类,而Meta类封装了一些数据库的信息。主要字段如下db_tableORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名class Meta:     db_table = "表名"2.index_together 联合索引3.unique_together 联合唯一索引4.ordering指定默认按什么字段排序 只有设置了该属性,我们查询到的结果才可以被reverse()

必会的查询操作

返回QuerySet的有:    1. all()    3. filter()    4. exclude()    7. values_list()  --> 元祖    8. values()       --> 字典    9. order_by()    10. reverse()    13. distinct()返回对象:      2. get()    5. first()    6. last()返回数字:    11. count()返回布尔值:    12. exist()  
<1> all():                 查询所有结果<2> filter(**kwargs):      得到结果集 是个列表<QuerySet [<Publisher: Publisher object>]>ret = models.Person.objects.filter(id=100) 不存在返回一个空的QuerySet,不会报错就算查询的结果只有一个,返回的也是QuerySet,我们要用索引的方式取出第一个元素ret = models.Person.objects.filter(id=1)[0]<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。<4> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象<5> values(*field):        返回一个可迭代的字典序列ret = models.Person.objects.values("name", "birthday") 返回一个QuerySet对象,里面都是字典。 不写字段名,默认查询所有字段<6> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列ret = models.Person.objects.values_list()<7> order_by(*field):      对查询结果排序ret = models.Person.objects.all().order_by("birthday")<8> reverse():             对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。 对有序的QuerySet才能调用reverse ret = models.Person.objects.all().count()<9> distinct():            从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)<10> count():              返回数据库中匹配查询(QuerySet)的对象数量。<11> first():              返回第一条记录<12> last():               返回最后一条记录<13> exists():             如果QuerySet包含数据,就返回True,否则返回False

#all
print(models.Book.objects.all()) #得到对象的集合 <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]>
#get
print(models.Publisher.objects.get(id=1))  #得到的是对象Publisher object.返回结果有且只有一个,不存在会报错
#filter
print(models.Publisher.objects.filter(id=1)) #得到结果集 是个列表<QuerySet [<Publisher: Publisher object>]>
# 不存在返回一个空的QuerySet,不会报错 用索引的方式取出第一个元素  ret = models.Person.objects.filter(id=1)[0]
# exclude得到不包含要求的对象
print(models.Book.objects.exclude(id=1)) #<QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]>
print(models.Book.objects.exclude(id=1)[0].title) #得到的是列表,使用索引得到指定的对象。得到其属性
#values返回 QuerySet对象 字典序列
print(models.Book.objects.values())
#<QuerySet [{‘id‘: 1, ‘title‘: ‘四世同堂‘, ‘publisher_id‘: 2}, {‘id‘: 2, ‘title‘: ‘python从入门到放弃‘, ‘publisher_id‘: 1}, {‘id‘: 3, ‘title‘: ‘后来的我们‘, ‘publisher_id‘: 2}]>
#取其属性
print(models.Book.objects.values()[1]["title"]) #python从入门到放弃
print(models.Book.objects.values("title","price"))
#values_list
print(models.Book.objects.values_list("title", "price"))
# order_by 按照指定的字段排序 升序
print(models.Book.objects.all().order_by( "price"))
#reverse
print(models.Person.objects.all().reverse())
#count
print(models.Book.objects.all().count())
# first 返回QuerySet中第一个对象
print(models.Book.objects.first())
# last 返回QuerySet中最后一个对象
print(models.Book.objects.all().last())
# exists 判断表里有没有数据
print(models.Book.objects.exists())

Django终端打印SQL语句

在Django项目的settings.py文件中,在最后复制粘贴如下代码:
LOGGING = {
    ‘version‘: 1,
    ‘disable_existing_loggers‘: False,
    ‘handlers‘: {
        ‘console‘:{
            ‘level‘:‘DEBUG‘,
            ‘class‘:‘logging.StreamHandler‘,
        },
    },
    ‘loggers‘: {
        ‘django.db.backends‘: {
            ‘handlers‘: [‘console‘],
            ‘propagate‘: True,
            ‘level‘:‘DEBUG‘,
        },
    }
}

Python脚本中调用Django环境

‘‘‘
import os
if __name__ == ‘__main__‘:
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings") #BMS为Django项目名
    import django
    django.setup()
‘‘‘

 
 
 
 
 
 
 

原文地址:https://www.cnblogs.com/zgf-666/p/9119337.html

时间: 2024-10-29 02:36:47

ORM的相关操作的相关文章

Django框架之ORM的相关操作

一.一般操作 from django.db import models import datetime # Create your models here. class Author(models.Model): id=models.AutoField(primary_key=True) name=models.CharField(max_length=20) # 以下是测试字段 numtest=models.IntegerField() datetest=models.DateField(nu

Django ORM那些相关操作

一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误. <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <5> values(*field): 返回

Django框架之ORM的相关操作之多对多三种方式(五)

在之前的博客中已经讲述了使用ORM的多对多关系表,现在进行总结一下: 1.ORM自动帮助我们创建第三张表 2.手动创建第三张表,第三张表使用ForeignKey指向其他的两张表关联起来 3.手动创建第三张表,使用的和ORM帮助我们创建的一样(这种方法暂时先不赘述) 该博客重点讲一下第二种方法:手动创建第三张表,并且第三张表使用ForeignKey指向其他两张表关联起来 以作者和出版的书进行举例子.作者可以写多本书,书也可以有多个作者,书与作者的关系就是多对多的关系 1.创建两张各自的表(作者表和

Django框架进阶5 models常用字段及参数, choices参数, 自动显示sql命令配置, orm查询优化相关, orm中的事务操作, MTV与MVC模型, 图书管理系统(图书的增删改查)

models中的常用字段 AutoField(primary_key=True) 主键   (int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列.) CharField(max_length=32)     varchar(32) IntegerField()       int BigIntergerField()           bigint DecimalField()    decimal EmailField(

cakephp v3.4 数据库相关操作

cakephp v3.4 数据库相关操作 查询对象 Query Objectclass Cake\ORM\Query 获取Query object表对象 Table Object 使用find()返回 1.任何情况下都可以从TableRegistry中获取use Cake\ORM\TableRegistry;$articles = TableRegistry::get('Articles');$query = $articles->find(); 2.在对应的控制器中(框架自动就创建了)$que

DjangoORM的相关操作

DjangoORM的相关操作 在python脚本中直接调用Django环境 import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm.settings") import django django.setup() 一般操作 必知必会13条 class Person(models.Model): name = models.Ch

17-2 orm单表操作和多表操作

参考:https://www.cnblogs.com/liwenzhou/p/8660826.html 一  ORM单表操作 1 增删改查 1 1. 查询 2 1. 查所有 3 models.Publisher.objects.all() 4 2. 查某个具体的记录 5 models.Publisher.objects.get(id=1) --> 注意查询条件不成立就报错 6 2. 删除一条记录 7 models.Publisher.objects.get(id=1).delete() 8 3.

ORM表相关操作

一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误. <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <5> values(*field): 返回

Django学习手册 - ORM 数据表操作

queryset 数据类型介绍 QuerySet与惰性机制 所谓惰性机制:表名.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行. QuerySet特点: <1>  可迭代的 <2>  可切片 <3>  惰性计算和缓存机制 例: info=models.table_name.objects.all()[0:5] #切片 info= models.table