• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

第二章(一)Django框架的模型Model、ORM操作数据库

武飞扬头像
冷凝娇
帮助1

系列文章目录

备注:这里是Django系列文章的所有文章的目录
第一章(一) : Django框架之创建项目/应用/templates、连接MYSQL、配置日志LOGGING、启动django项目
第一章(二):Django框架的模式、路由、视图;
第一章(三):Django框架的视图函数、视图类的认识及常规使用;
第一章(四):Django框架的模板(DTL):变量、标签、模板过滤器、模板继承、配置模板文件(staticfiles)


备注:欢迎查阅python之Django框架,如有疑问,欢迎评论,一定回复!!!


前言

提示:这里是本文要记录的大概内容:

模型(Model)是 MTV 模式的重要组成部分。在 Django 框架中,主要通过模型来实现与数据库的交互功能,如数据的增加、删除、修改和查询,以及多表关联等。


一、Django模型的定义

在Diango框架中,模型用于描述数据库表结构。模型实例可以实现数据操作。一个模型( Model)对应一个数据库表。模型中的字段对应数据库表中的一个字段
在定义好一个模型后,Django 会提供数据库访问的一整套 API,从而自动在数据库中生成相应的数据表,这样就不需要使用 SOL 脚本创建表,或者在数据库中手工创建表格了,大大提高了开发效率。

1.1 Model定义的示例

  1. 在app4/models.py文件中:
from django.db import models
# Create your models here.

class UserBaseInfo(models.Model):
    id = models.AutoField(verbose_name='编号', primary_key=True)
    username = models.CharField(verbose_name='用户名称', max_length=30)
    password = models.CharField(verbose_name='密码', max_length=20)
    status = models.CharField(verbose_name='状态', max_length=1)
    createdate = models.DateTimeField(verbose_name='创建日期', db_column='createDate')
    def __str__(self):
        return str(self.id)

    class Meta:
        verbose_name = '人员基本信息'
        db_table = 'UserBaseInfo4'

在上述代码中,定义了一个人员基本信息的模型,其中包括编号、用户名称、密码、状态等段。这些字段有整数类型、字符类型和日期类型。每个字段还包括名称、长度、是否主键等参数;

2.1 Django模型的字段常用类型

学新通

data_types = {
        "AutoField": "integer AUTO_INCREMENT",
        "BigAutoField": "bigint AUTO_INCREMENT",
        "BinaryField": "longblob",
        "BooleanField": "bool",
        "CharField": "varchar(%(max_length)s)",
        "DateField": "date",
        "DateTimeField": "datetime(6)",
        "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)",
        "JSONField": "json",
        "OneToOneField": "integer",
        "PositiveBigIntegerField": "bigint UNSIGNED",
        "PositiveIntegerField": "integer UNSIGNED",
        "PositiveSmallIntegerField": "smallint UNSIGNED",
        "SlugField": "varchar(%(max_length)s)",
        "SmallAutoField": "smallint AUTO_INCREMENT",
        "SmallIntegerField": "smallint",
        "TextField": "longtext",
        "TimeField": "time(6)",
        "UUIDField": "char(32)",
    }
学新通

3.1 模型常用字段参数

3.1.1 数值型字段 DecimalField 的参数

该类型字段表示:固定精度十进制数。具体语法如下:

models.DecimalField(max digits=None, decimal places=None)

其中参数如下:

  • maxdigits: 数字允许的最大位数
  • decimal_places:小数的最大位数

3.1.2 时间日期类型字段: DatetimeField、DateField和TimeField 的参数

  • 3个字段都有auto_now_add 和auto_now 参数
  • auto_now_add : 将时间类型字段的值设置为创建时的时间,后期不能再次修改,比如用户注册时间。该参数默认为 False。一旦设置为 True,则无法在程序中手动为字段赋值。
  • auto_now : 将时间类型字段设置为当前时间,比如用户登录时间、某条数据的最后修改时间。该参数默认为 False。一旦设置为 True,则无法在程序中手动为字段赋值。

如果要把时间类型字段设置为当前默认时间,并且还能在程序中进行修改,则使用如下代码:

from django.db import models
import django.utils.timezone as timezone
class User(models.Model):
	createDate = models.DateTimeField('创建日期',default = timezone.now)

3.1.3 常用字段参数

  • verbose_name : 设置字段的显示名称
  • primary_key : 设置字段为主键
  • editable :是否可以编辑,一般用于admin后台
  • max_length : 设置字段的最大长度
  • blank :若为True,则该字段允许为空值,在数据库中表现为空字符串。默认为False
  • null : 若为 True,则该字段允许为空值,在数据库中表现为null。默认为 False
  • default : 设置字段的默认值
  • choices : 设置字段的可选值
  • db_column : 设置表中的列名称。如果不设置,则将字段名作为列名称
  • db_index : 数据库中的字段是否可以建立索引
  • unique : 数据库中字段是否可以建立唯一索引
  • error_messages: 自定义错误信息(字典类型)
  • validators : 自定义错误验证(列表类型)

3.1.4 模型定义类中,str()方法的作用

str()()方法用来设置模型的返回值,其默认返回值为“模型对象”。
举例:设置模型的返回值为“主键ID 用户名”。

    def __str__(self):
        return str(self.id) self.username

3.1.5 模型定义类中,Meta类的作用

备注:Meta类示例见 1.1

Django 模型中的 Meta 类是一个内部类,用于定义一些 Django 模型的行为特性。其常用参数如下:

  • abstract: 若为True,则该模型类为抽象类
  • db_table: 设置模型对象的数据表名称。若不设置,则默认设置数据表名称为“应用名 下划线 模型类名”
  • managed: 默认为True.Django会管理数据表的生命周期,包括迁移等
  • ordering: 模型对象返回的记录结果集按照哪个字段排序,一般设置如下:
    ordring=[“create_date”] #按照创建时间升序排列
    ordring=[“-create_date”] #按照创建时间降序排列
    ordring=[“-create_date”,“orderid”] #按照创建时间降序排列,再以订单编号升序排列
  • verbose_name : 模型类在后台管理中显示的名称,一般为中文
  • index_together:多个字段的联合索引
  • unique_together: 多个字段的联合约束,比如,购物车表中每一行的用户和商品字段必须唯一,不能重复

二、了解模型中的关系

数据库中的表存在关联关系,包含“一对一”、“一对多”、“多对多”关系。Django中的模型对应数据库中的表,因此,Django中的模型也存在这些关系。

2.1.“一对一”关系

代码如下(示例):models.OneToOneField(UserBaseInfo, on_delete=models.CASCADE)

在app4/models.py模型文件中:

from django.db import models
from django.urls import reverse
# Create your models here.

class UserBaseInfo(models.Model):
    id = models.AutoField(verbose_name='编号', primary_key=True)
    username = models.CharField(verbose_name='用户名称', max_length=30)
    password = models.CharField(verbose_name='密码', max_length=20)
    status = models.CharField(verbose_name='状态', max_length=1)
    createdate = models.DateTimeField(verbose_name='创建日期', db_column='createDate')

    def __str__(self):
        return str(self.id) self.username

    def get_absolute_url(self):
        return reverse('app4_userinfo', kwargs={'id': self.pk})

    class Meta:
        verbose_name = '人员基本信息'
        db_table = 'UserBaseInfo4'


class UserExtraInfo(models.Model):
    id = models.AutoField(verbose_name='扩展编号', primary_key=True)
    username = models.CharField(verbose_name='用户名称', max_length=30)
    truename = models.CharField(verbose_name='真实姓名', max_length=30)
    password = models.CharField(verbose_name='密码', max_length=20)
    birthday = models.DateTimeField(verbose_name='出生日期', db_column='birthday')
    sex_choice = (
        (0, '女性'),
        (1, '男性'),
    )
    sex = models.IntegerField(choices=sex_choice, default=1)
    email = models.CharField(verbose_name='邮箱', max_length=40)
    age = models.IntegerField(verbose_name='年龄')
    # 一对一关联关系
    user = models.OneToOneField(UserBaseInfo, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.id)

    class Meta:
        verbose_name = '人员扩展信息'
        db_table = 'UserExtraInfo4'
学新通

2.1.1 OneToOneField()方法中参数及参数的配置项

学新通

2.2.“一对多”关系

使用 ForeignKey()方法来构建模型的“一对多”关系。

2.2.1 ForeignKey()放在哪张数据表对应的模型中?

答:哪个数据表需要外键,就把 ForeignKey()方法放到该数据表对应的模型中;

`外键:一定是创建在数据表关系【一对多】中【多】的那个表中;`

学新通

具体见:
Django框架(十一):Models之ORM对单表的增.删.改(从web页面操作后,数据库存入数据)/ORM查询API、双下划线作用
Django框架(十二):Models之ORM对多表【一对多】的操作(增、删、改、查)

2.3.“多对多”关系

例举:用户扩展信息表与技能信息表即多对多关系:一个用户可以多项技能,一个技能也可对应多个用户。模型中,使用ManyToManyField()方法来构建模型的“多对多”关系。

参数 含义
to 要进行关联的模型名称
db_constraint=True 是否在数据库中创建外键约束
db_table=None 默认创建的多对多关系表的表名

在ManyToMany()方法中,没有on_delete参数;db_table参数表示模型迁移后生成的多对多关系表的表名(即:中间表),如果不设定,则默认生成的表名为:“两个模型名称的相加”

2.3.1 创建多对多关系表的三种方式,【推荐:第3种

2.3.1.1 创建多对多关系表的第1种方法:ManyToManyField()
class Book(models.Model):
    name = models.CharField(max_length=20)
    price = models.IntegerField()
    pub_date = models.DateField()


class Author(models.Model):
    name = models.CharField(max_length=50, verbose_name='作者姓名')
    books = models.ManyToManyField(to='Book') # 使用ManyToManyField,由django自动创建第3张中间表,在model中没有class,不可扩展;
2.3.1.2 创建多对多关系表的第2种方法:自己创建第3张表
class Book(models.Model):
    name = models.CharField(max_length=20)
    price = models.IntegerField()
    pub_date = models.DateField()

class Author(models.Model):
    name = models.CharField(max_length=50, verbose_name='作者姓名')

class Author2Book(models.Model):#自己创建中间表
    author = models.ForeignKey(Author, on_delete=models.DO_NOTHING)
    book = models.ForeignKey(Book, on_delete=models.DO_NOTHING)
2.3.1.3 创建多对多关系表的第3种方法:ManyToManyField() 自己创建第3张表
class Book(models.Model):
    name = models.CharField(max_length=20)
    price = models.IntegerField()
    pub_date = models.DateField()


class Author(models.Model):
    name = models.CharField(max_length=50, verbose_name='作者姓名')
    books = models.ManyToManyField(to='Book', through='Author2Book', through_fields=('author', 'book'))  # 关联关系
    # 解释的参数:
    # to  : 与哪张表建立多对多关系;
    # through  :  通过第3张表实现‘多对多’关系
    # through_fields :通过第3张表中的哪两个字段实现‘多对多’关系,一般是:('本表名小写,也是第3张表的字段之一','另一张表小写,也是第3张表的字段之一')


class Author2Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.DO_NOTHING) #要加上on_delete,否则会报错
    book = models.ForeignKey(Book, on_delete=models.DO_NOTHING)

    class Meta:
        unique_together = ('author', 'book')  # 建立联合约束,即:该表的每一行数据,作者和书籍必须唯一,不能重复
学新通

学新通
学新通
学新通

Django框架(十三):Models之ORM对多表【多对多】的操作(增、删、改、查)

三、Django中的ORM操作数据库

ORM的作用:在关系型数据库和业务实体对象之间进行映射。
类----数据表
属性----字段
实例----数据行

3.0. 创建好Models后,setting配置OK后,进行数据迁移

python manage.py makemigrations
python manage.py migrate

分别成功后,数据库的操作就可正常进行了。具体访问:Django框架(十):Models之ORM(sqilte数据库、mysql数据库在django中如何快速创建表,如何在pycharm中操作)

3.1. IPython增强的交互式解释器

Django 的manage工具提供了shell命令,帮助我们直接在终端执行测试Python语句。命令如下:

python manage.py shell

学新通
其中,In提示符用于输入语句,Out提示符则显示输出内容。
如果没有绿色的In[1]这样的字样,需要安装ipython,⚠️备注:ipython是基于python默认cpython解释器之上的交互式解释器,提供了:颜色显示、tab补全、历史机制、集成python调试器等功能。

pip install ipython

3.2. QuerySet对象,又称:查询集

QuerySet对象也被称为“查询集”,表示:从数据库获取的数据对象集合。其有一个重要特性:惰性执行🔍什么是集合

3.2.1 解释QuerySet对象(又称:查询集)的惰性执行

惰性执行:在创建查询集后不会访问数据库,只有在调用相关方法时才会访问数据库。如:遍历迭代、序列化等才会。

queryset = UserBaseInfo.objects.all()    #还没有对数据库进行访问
for user in queryset :                   #开始操作数据库
	print(user.username)

3.2.2 QuerySet对象 的 all() 方法

queryset = UserBaseInfo.objects.all()    #查询所有数据
print(queryset[0].username)            #打印第1条数据的username字段值,索引从0开始

在PyCharm终端进行测试;使用python manage.py shell 加上3.1 所描述的IPython解释器;
学新通

3.2.3 QuerySet对象 的filter()方法

filter() 方法用于实现数据过滤,相当于SQL中的where子句。返回:QuerySet对象;⚠️备注:如过没有获取到数据,返回:空QuerySet对象。

模型类.objects.filter(字段=值)
users = UserExtraInfo.objects.filter(sex=1)    #查询性别为1的用户
print(users[0].username)                       #打印第1个用户名称

学新通

3.2.4 objects对象的get()方法:返回的一条数据,以 模型对象 类型,不是查询集

  1. 该方法用于查询数据表记录,以模型对象的形式返回符合要求的一条数据;
  2. 当查询没有记录或者记录数超过一条时 ,会出现错误提示,因此需要做异常捕获处理;
user = UserExtraInfo.objects.get(id=1) # 获取id为1的数据,返回对象,注意这里不是查询集,可直接打印
print(user)
print(user.truename)

学新通
当get()方法查询没有记录或者超过1条时,报错如下:
学新通

3.2.5 QuerySet对象 的exclude() 方法

用户查询排除条件的数据,返回QuerySet对象

user = UserExtraInfo.objects.exclude(age__lt=32)# 查询排除age小于32的用户,返回QuerySet对象

学新通

3.2.6 QuerySet对象 的values() 方法

该方法用于获取需要的字段。返回QuerySet对象,对象包括的数据类型是由dict类型数据组成

users = UserExtraInfo.objects.values() #select * from userextrainfo
users = UserExtraInfo.objects.values('id','username','truename') #select id,username,truename from userextrainfo

学新通
学新通

3.2.7 QuerySet对象 的distinct() 方法

该方法用于去除重复数据,返回QuerySet对象

UserBaseInfo.objects.distinct().values('depart')# select DISTINCT 'depart' from userbaseinfo

学新通

3.3. 常见的操作符,在filter、exclude方法中使用。

可以在filter()、exclude()方法中使用大于、小于、模糊匹配等操作符。

3.3.1 常见的操作符 及 具体使用

操作符 含义 具体使用
__gt 大于 filter(age__gt=20)
__gte 大于或等于 filter(age__gte=20)
__lt 小于 filter(age__lt=20)
__lte 小于或等于 filter(age__lte=20)
__in 在某个列表内 filter(sex__in=[1,0])
__contains 模糊匹配 filter(name__contains=‘张’)
__year 日期字段的年份 right-aligned 文本居右
__month 日期字段的月份 right-aligned 文本居右
__day 日期字段的天数 right-aligned 文本居右

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhejjh
系列文章
更多 icon
同类精品
更多 icon
继续加载