计算机基础知识62

模型层回顾:基本使用

模型层有orm框架:对象关系映射

数据库中:一个个表 :user表,book表,一条条的记录

程序中:一个个类,一个个对象

数据库中一张表---->程序中一个类

数据库中一条记录---->对应程序中一个对象

迁移数据库:

python 复制代码
models.py
from django.db import models
# 写一个个类
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=64, null=False)
    price = models.DecimalField(max_digits=7, decimal_places=2) 
# 执行命令
python manage.py makemigrations
python manage.py migrate   
    

常用和非常用字段(熟悉)

数据库表中字段有很多类型 : int,varchar,text

数据库表中字段有很多类型:

javascript 复制代码
AutoField(Field)-int自增列,必须填入参数 primary_key=True
BigAutoField(AutoField)-bigint自增列,必须填入参数 primary_key=True

SmallIntegerField(IntegerField)-小整数 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)-正小整数 0 ~ 32767
IntegerField(Field)- 整数列(有符号的) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)- 正整数 0 ~ 2147483647
BigIntegerField(IntegerField)- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

BooleanField(Field)- 布尔值类型
NullBooleanField(Field)- 可以为空的布尔值

CharField(Field)- 字符类型- 必须提供max_length参数 max_length表示字符长度
TextField(Field)- 文本类型
FileField(Field)- 字符串,路径保存在数据库,文件上传到指定目录
    - 参数:upload_to = ""      上传文件的保存路径
          storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

EmailField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证机制
IPAddressField(Field)- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
URLField(CharField)- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField(CharField)- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
CommaSeparatedIntegerField(CharField)- 字符串类型,格式必须为逗号分割的数字
UUIDField(Field)- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能   
    - 参数:path,                      文件夹路径
            match=None,                正则匹配
            recursive=False,           递归下面的文件夹
            allow_files=True,          允许文件
            allow_folders=False,       允许文件夹

ImageField(FileField)- 字符串,路径保存在数据库,文件上传到指定目录    
- 参数:upload_to = ""      上传文件的保存路径
        storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
        width_field=None,   上传图片的高度保存的数据库字段名(字符串)
        height_field=None   上传图片的宽度保存的数据库字段名(字符串)

DateTimeField(DateField)- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)- 日期格式      YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field)- 时间格式      HH:MM[:ss[.uuuuuu]]
DurationField(Field)- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

FloatField(Field)- 浮点型
BinaryField(Field)- 二进制类型
DecimalField(Field) - 10进制小数
    - 参数:max_digits,小数总长度
           decimal_places,小数位长度

常用非常用字段参数

null:如果为True,Django 将用NULL 来在数据库中存储空值,默认值是 False.
blank: 后台管理,用的少,如果为True,该字段允许不填。默认为False。

要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。

如果一个字段的blank=True,表单的验证将允许该字段是空。

如果字段的blank=False,该字段就是必填的。
default:字段的默认值。可以是一个值或者可调用对象。

如果可调用 ,每有新对象被创建它都会被调用。
primary_key:如果为True,那么这个字段就是模型的主键。

如果你没有指定任何一个字段的primary_key=True,Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,否则没必要设置任何一个字段的primary_key=True。
unique:如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的

db_index :该字段建立索引

choices:

由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。

python 复制代码
from django.db import models
class Person(models.Model):
    # 每个元组的第二个元素用来在amdin管理界面显示,而第一个元素才是被存入数据库中的值
    SHIRT_SIZES = (
        ('S', 'Small'),
        ('M', 'Medium'),
        ('L', 'Large'),
    )
    name = models.CharField(max_length=60)
    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
p = Person(name="Fred Flintstone", shirt_size="L")
p.save()
p.shirt_size  #'L'
p.get_shirt_size_display() # 'Large',取值

关于Meta中:

python 复制代码
class UserInfo(models.Model):
       nid = models.AutoField(primary_key=True,index=True)
       username = models.CharField(max_length=32)
       mobile=models.CharField(max_length=32)
       class Meta:
           # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
           db_table = "table_name"  # 改表名
           # 联合索引
           index_together = [
               ("username", "mobile"),
           ]
           # 联合唯一索引
           unique_together = (("username", "mobile"),)
           # admin中显示的表名称
           verbose_name='图书表'
           # verbose_name加s
           verbose_name_plural

settings配置

orm 可以操作:sqlite,mysql,oracle,postgresql...

配置文件中的配置:

默认配置:操作sqlite:

python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite_lqz',
    }
}

操作mysql:

python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day05',
        'HOST':'127.0.0.1',
        'PORT':3306,
        'USER':'root',
        'PASSWORD':'JIAJIA',
    }
}

#装模块:pymsql模块,mysqlclient

python 复制代码
pip3 install mysqlclient   #其他不需要任何操作----有可能在你机器装不上,mac
pip3 install pymysql --upgrade   # 更新最新版本

保证它执行,放在配置文件中__init__.py

python 复制代码
import pymysql
pymysql.install_as_MySQLdb()

基本操作(增删改查)

增加删除字段,只需要在表模型,增加,注释字段,增加删除字段参数,再迁移就可以了

python 复制代码
增加表记录
# 方案一:
Book.object.create()
#方案二:
book=Book(参数)
book.save()

不要轻易删除迁移记录

python 复制代码
# 删除方式一:查出来再删
Book.objects.all().delete()
# 删除方式二:可以重写类中得delete方法
book=Book.objects.filter(pk=1).first()
book.delete() #Book 类中有个delete方法,咱们没有写---》父类的--》可以重写

更新:

python 复制代码
# 更新方式一:查出来再删
Book.objects.all().update()
# 更新方式二:    
book=Book.objects.filter(pk=1).first()
book.name='ss'
book.save()

#查:

javascript 复制代码
all():                  查询所有结果
filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
order_by(*field):       对查询结果排序('-id')
reverse():              对查询结果反向排序
count():                返回数据库中匹配查询(QuerySet)的对象数量。
first():                返回第一条记录
last():                返回最后一条记录
exists():              如果QuerySet包含数据,就返回True,否则返回False
values(*field):        返回一个ValueQuerySet------一个特殊的QuerySet,运行后得到是一个可迭代的字典序列
values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
distinct():            从返回结果中剔除重复纪录

多表操作-创建关系

python 复制代码
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
    #这不是个字段
    authors=models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail',unique=True,on_delete=models.CASCADE)

class AuthorDatail(models.Model):
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)

class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

关联关系有:

一对一:本质就是一对多,只不过多的字段唯一

一对多:外键关联

多对多:必须要有中间表

OneToOneField:ForeignKey 必须写on_delete,不写报错

on_delete的参数:

models.CASCADE :级联删除,删除出版社,当前出版社下所有的图书数据都会被删除
models.SET_NULL :删除出版社,当前出版社下所有的图书数据publish_id字段都是置为空
models.SET_DEFAULT :删除出版社,出版社下所有图书数据publish_id字段都设为默认值
models.SET(值/可调用对象):

删除出版社,当前出版社下所有的图书数据都会的publish_id字段都设为SET传入的值,如果是可调用对象,会执行可调用对象,把return传入
models.DO_NOTHING :publish_id字段原封不动

python 复制代码
publish = models.ForeignKey(to='Publish',on_delete=models.SET_NULL,null=True)
publish = models.ForeignKey(to='Publish',on_delete=models.SET_DEFAULT,default=1)
publish = models.ForeignKey(to='Publish',on_delete=models.DO_NOTHING,db_constraint=False)

基于对象的跨表查询

基于对象的跨表查询

假设拿到book对象: 对象=对象.字段

python 复制代码
book.name
book.price
book.publish_id ---->出版社id号---》咱们可以通过出版社id,再去出版社表,查出当前出版社,很麻烦
-----快捷方式-----
book.publish---->拿到的是   publish对象---》当前图书的出版社对象
book.publish.继续往后点击
publish=book.pulish

有正向查询和 反向查询---》拿到的都是对象

正向:当前表中,有那个字段,类似于:book.pulish author.author_detail

通过字段

反向:当前表中,没有那个字段 author_detail.author

通过author_detail拿到author

通过表名小写

一对一正反向

python 复制代码
text_use.py
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'check_table.settings')
import django
django.setup()
from app01.models import Book,Author,AuthorDatail,Publish
if __name__ == '__main__':
    # 一对一正反向
    # 正向
    author = Author.objects.all().first()
    print(author.author_detail.addr)
    # 反向
    author_datail = AuthorDatail.objects.filter(pk=2).first()
    author = author_datail.author.name
    # telephone = author_datail.telephone
    # addr = author_datail.addr
    print(author)

一对多正反向

python 复制代码
if __name__ == '__main__':
    # 正向
    book = Book.objects.all().first()
    publish = book.publish.name
    print(publish)
    # 反向
    publish = Publish.objects.filter(pk=2).first()
    book = publish.book_set.all()
    # print(book)  #<QuerySet [<Book: 西游记>, <Book: 红楼梦>]>
    print(book)  # <QuerySet [<Book: 三国演义>]>

多对多正反向

正向: 拿到当前图书所有作者

反向 拿到当前作者写的所有图书

python 复制代码
if __name__ == '__main__':
    # 多对多
    # 正向
    book = Book.objects.filter(pk=3).first()
    author = book.authors.all()
    print(author)
    # 反向
    author = Author.objects.filter(pk=1).first()
    book = author.book_set.all()
    print(book)  #<QuerySet [<Book: 西游记>, <Book: 三国演义>]>

基于链表的跨表查询

一对一链表- 正反向

python 复制代码
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'check_table.settings')
import django
django.setup()
from app01.models import Book,Author,AuthorDatail,Publish
if __name__ == '__main__':
    # 一对一链表--->拿出id为1的作者的地址
    # 通过__链表
    # 正向
    res = Author.objects.filter(pk=1).values('id','name','author_detail__addr')
    print(res)
    # 反向
    res = AuthorDatail.objects.filter(addr='上海').values('addr','author__name')
    print(res)  #<QuerySet [{'addr': '上海', 'author__name': '周佳祺'}]>

一对多正反向

python 复制代码
if __name__ == '__main__':
    # 正向
    # 查询上海出版社出版过的所有书籍的名字与价格(一对多)
    res = Publish.objects.filter(name='上海出版社').values('name','book__name','book__price')
    print(res)
    # 反向
    res = Book.objects.filter(pk=1).values('id','publish__name')
    print(res)

多对多关系

python 复制代码
if __name__ == '__main__':
    # 查询周佳祺出过的所有书籍的名字(多对多)
    # 正向
    res = Author.objects.filter(name='周佳祺').values('name','book__name')
    print(res)  #<QuerySet [{'name': '周佳祺', 'book__name': '西游记'}, {'name': '周佳祺', 'book__name': '三国演义'}]>
    # 反向
    res = Book.objects.filter(name='西游记').values('name','authors__name')
    print(res)

# 查询红楼梦这本书出版社的名字####

查询上海出版社出版过的所有书籍的名字以及作者的姓名

python 复制代码
if __name__ == '__main__':
    # 查询上海出版社出版过的所有书籍的名字以及作者的姓名
    # 正向
    res = Publish.objects.filter(name='上海出版社').values('book__name','book__authors__name')
    print(res)
    # 反向
    res = Book.objects.filter(name='西游记').values('authors__name','authors__author_detail__telephone')
    print(res)

表查询练习

查询红楼梦这本书出版社的名字

查询红楼梦这本书出版社的名字

手机号以151开头的作者出版过的所有书籍名称以及出版社名称

查询手机号以33开头的作者出版过的书籍名称以及书籍出版社名

查找所有书名里包含红楼的书

查找出版日期是2017年的书

查找出版日期是2017年的书名

查找价格大于10元的书

查找价格大于10元的书名和价格

查找在北京的出版社

查找名字以沙河开头的出版社

查找作者名字里面带"小"字的作者

查找年龄大于30岁的作者

查找手机号是155开头的作者

查找手机号是155开头的作者的姓名和年龄

查找书名是"红楼梦"的书的出版社

查找书名是"红楼梦"的书的出版社所在的城市

查找书名是"红楼梦"的书的出版社的名称

查找书名是"红楼梦"的书的所有作者

查找书名是"红楼梦"的书的作者的年龄

查找书名是"红楼梦"的书的作者的手机号码

查找书名是"红楼梦"的书的作者的地址

查找书名是"红楼梦"的书的作者的邮箱

今日思维导图:

相关推荐
南城花随雪。4 分钟前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了5 分钟前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
懒是一种态度7 分钟前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
天海华兮9 分钟前
mysql 去重 补全 取出重复 变量 函数 和存储过程
数据库·mysql
gma9991 小时前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️1 小时前
华为ASP与CSP是什么?
服务器·前端·数据库
陈王卜1 小时前
django+boostrap实现发布博客权限控制
java·前端·django
Yz98762 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
苏-言2 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
Ljw...2 小时前
索引(MySQL)
数据库·mysql·索引