2-6.ORM基础

django orm简介

# 什么是ORM?
	ORM:对象关系映射
# 为什么要用ORM?
	能够让不会写SQL语句的python程序员 
    使用面向对象的语法即可简单快捷的操作MySQL,极大地提升开发效率
	'''但是ORM有时候自动生成的SQL效率可能会很低'''

类			表
对象			一行行记录
对象点属性     记录某个字段对应的值
# 如何使用ORM?
	在django应用文件夹下的models.py中操作
  
"""orm无法创建库 需要自己提前创建好"""

orm创建表

"""
强调:只要在models.py中改动了与数据库相关的代码 就必须要重新执行迁移命令
"""

# 1.先在models.py中书写类相关的代码
# 2.执行数据库迁移命令
	python3 manage.py makemigrations # 将改动记到小本本上(migrations)
    python3 manage.py migrate  # 真正操作数据库
    """pycharm快捷提示(tools>>>run manage.py task)"""

字段增删改查

# 当表中已经有数据存在的情况下如果添加新的字段那么需要设置null或者default
password = models.IntegerField(verbose_name='密码',null=True)  # pwd int comment '密码'
age = models.IntegerField('年龄',default=18)

数据增删改查

# 查
models.User.objects.all()  # 查询user表中所有的数据
	# select * from user;
	<QuerySet [<User: jason>, <User: tony>, <User: kevin>]>
models.User.objects.filter(name='jason')  # 查询name=jason的数据
	# select * from user where name='jason'
    <QuerySet [<User: jason>]>
models.User.objects.filter(name='jason',password=123)
	# select * from user where name='jason' and password=123
    <QuerySet [<User: jason>]>
"""
QuerySet我们可以简单的理解为是列表套一个个数据对象
"""

# 增
models.User.objects.create(name='jerry',password=567)
	# insert into user(name,password) values('jerry',567)
    上述orm返回值为当前被创建出来的数据对象本身
    
obj = models.User(name='tom',password=111)  # 类产生对象
obj.name ='oscar'
obj.save()  # 对象调用save方法保存到数据库

# 改
edit_obj = models.User.objects.filter(id=3)[0]
edit_obj.name = 'kevinSB'
edit_obj.save()

models.User.objects.filter(name='jason').update(name='jasonNB')
	# update user set name='jasonNB' where name='jason';
   
# 删
models.User.objects.filter(id=5).delete()
	# delete from user where id=5;

orm外键创建

一对多外键关系  
	"""在orm中 外键字段建在多的一方"""
多对多外键关系
	"""在orm中 可以直接写在查询频率较高的表中(自动创建第三张表)"""
一对一外键关系
	"""在orm中 直接写在查询频率较高的表中"""
    
# 一对多
    publish = models.ForeignKey(to='Publish')
# 多对多
    authors = models.ManyToManyField(to='Author')  # 自动创建书籍和作者的第三张关系表
# 一对一
    author_detail = models.OneToOneField(to='AuthorDetail')
    
"""
ForeignKey OneToOneField  会自动给字段加_id后缀
"""
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    # 一对多
    publish = models.ForeignKey(to='Publish')
    # 多对多
    authors = models.ManyToManyField(to='Author')  # 自动创建书籍和作者的第三张关系表

class Publish(models.Model):
    title = models.CharField(max_length=32)

class Author(models.Model):
    name = models.CharField(max_length=32)
    # 一对一
    author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):
    addr = models.CharField(max_length=32)
    phone = models.BigIntegerField()

补充

1.主键字段orm会自动创建 只不过名字固定为id
2.CharField字段类型必须要有max_length参数

表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时。
id字段是自动添加的,如果你想要指定自定义主键,只需在其中一个字段中指定 primary_key=True 即可。如果Django发现你已经明确地设置了Field.primary_key,它将不会添加自动ID列。
本示例中的CREATE TABLE SQL使用PostgreSQL语法进行格式化,但值得注意的是,Django会根据配置文件中指定的数据库后端类型来生成相应的SQL语句。

Django ORM 常用字段和参数

常用字段

AutoField

int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

IntegerField

一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)

CharField

字符类型,必须提供max_length参数, max_length表示字符长度。

这里需要知道的是Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段,但是Django允许我们自定义新的字段,下面我来自定义对应于数据库的char类型

img

自定义字段在实际项目应用中可能会经常用到

from django.db import models

# Create your models here.
#Django中没有对应的char类型字段,但是我们可以自己创建
class FixCharField(models.Field):
    '''
    自定义的char类型的字段类
    '''
    def __init__(self,max_length,*args,**kwargs):
        self.max_length=max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        '''
        限定生成的数据库表字段类型char,长度为max_length指定的值
        :param connection:
        :return:
        '''
        return 'char(%s)'%self.max_length
#应用上面自定义的char类型
class Class(models.Model):
    id=models.AutoField(primary_key=True)
    title=models.CharField(max_length=32)
    class_name=FixCharField(max_length=16)
    gender_choice=((1,'男'),(2,'女'),(3,'保密'))
    gender=models.SmallIntegerField(choices=gender_choice,default=3)

DateField

日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。

DateTimeField

日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

ORM和sql对应关系

对应关系:
    'AutoField': 'integer AUTO_INCREMENT',
    'BigAutoField': 'bigint AUTO_INCREMENT',
    'BinaryField': 'longblob',
    'BooleanField': 'bool',
    'CharField': 'varchar(%(max_length)s)',
    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'varchar(%(max_length)s)',
    'FilePathField': 'varchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'integer',
    'BigIntegerField': 'bigint',
    'IPAddressField': 'char(15)',
    'GenericIPAddressField': 'char(39)',
    'NullBooleanField': 'bool',
    'OneToOneField': 'integer',
    'PositiveIntegerField': 'integer UNSIGNED',
    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    'SlugField': 'varchar(%(max_length)s)',
    'SmallIntegerField': 'smallint',
    'TextField': 'longtext',
    'TimeField': 'time',
    'UUIDField': 'char(32)',

参数

字段参数

null	用于表示某个字段可以为空。

unique	如果设置为unique=True 则该字段在此表中必须是唯一的 。

db_index	如果db_index=True 则代表着为此字段设置索引。

default		为该字段设置默认值。


DateField和DateTimeField

auto_now_add	配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

auto_now	配置上auto_now=True,每次更新数据记录的时候会更新该字段。

关系字段

ForeignKey

外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。

ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。

字段参数

to 	设置要关联的表

to_field  	设置要关联的表的字段

on_delete	当删除关联表中的数据时,当前表与其关联的行的行为。

models.CASCADE		删除关联数据,与之关联也删除

db_constraint		是否在数据库中创建外键约束,默认为True。

OneToOneField

一对一字段。

通常一对一字段用来扩展已有字段。(通俗的说就是一个人的所有信息不是放在一张表里面的,简单的信息一张表,隐私的信息另一张表,之间通过一对一外键关联)

to
设置要关联的表。

to_field
设置要关联的字段。

on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。

测试文件配置

在进行一般操作时先配置一下参数,使得我们可以直接在Django页面中运行我们的测试脚本

在Python脚本中调用Django环境

img

orm查询操作

models.User.objects.all()  # 查询user表中所有的数据

<1> all(): 查询所有结果

<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象

<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

<4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象

<5> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列

<6> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

<7> order_by(*field): 对查询结果排序

<8> reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法。

<9> distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。

models.User.objects.all() # 查询user表中所有的数据

<11> first(): 返回第一条记录

<12> last(): 返回最后一条记录

<13> exists(): 如果QuerySet包含数据,就返回True,否则返回False

返回QuerySet对象的方法有

all()

filter()

exclude()

order_by()

reverse()

distinct()

特殊的QuerySet

values()       返回一个可迭代的字典序列

values_list() 返回一个可迭代的元祖序列

返回具体对象的

get()

first()

last()

返回布尔值的方法有:

exists()

返回数字的方法有

count()
posted @ 2021-12-26 14:09  OVO_3V3  阅读(35)  评论(0编辑  收藏  举报