Django模型层字段类型、字段属性,对数据库表进行增、删、改、查操作方法(models)

本文详细介绍了Django模型层的字段类型、字段属性及其在数据库操作中的应用,包括BooleanField、CharField、DateField等。此外,还讨论了如何通过模型进行对象的创建、查找、修改和删除,以及模型的元属性如abstract、app_label等,为Django数据库交互提供了清晰的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模型层

配置Mysql数据库

在确保mysql数据库可以连接使用的情况下;

首先在数据库中创建专为django使用的库django_models

create database django_models charset=utf8;

配置django的settings.py文件中的DATABASES属性如下

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # 数据库引擎
        'NAME': "django_models ", # 使用的数据库名
        "USER": "root", # 用户名
        "PASSWORD": "woaini21g", # 数据库密码
        "HOST": "localhost", # 数据库主机地址
        "PORT": "3306"  # 端口号
    }
}

由于使用djangoPython版本为3+;

此时对于mysql的支持已经变为pymysql,而对于django加载数据库引擎时还需要使用2版本的mysqldb名称

现在先需要我们安装pymysql之后在项目中重申mysql引擎

  1. 首先安装pymysql
 pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple
  1. 项目主目录下的__init__文件中添加如下内容

    import pymysql
    pymysql.install_as_MySQLdb()
    
  2. 现在整个项目的数据库使用已经切换到了mysql

模型层字段

在模型层类中的字段即是数据库中表的字段,表的字段设计非常重要

每一个字段都是Field基类的一个实例(Field类用来建立字段与数据库之间的映射)

模型字段定义不能以下划线结尾

  • django会根据在模型类中定义的字段属性来确定以下几点工作
    • 数据库中使用的数据类型
    • 模型类对应的表单类渲染时使用的表单类型及HTML部件
    • 必填字段等最低限度的验证要求检查,包括admin界面下自动生成的表单
BooleanField

BooleanField(**options):True/False字段,默认值为None

表单类型:CheckboxInput<input type='checkbox' ...>

CharField

CharField(max_length=None):字符串字段

含有一个必须参数:max_length设置最大的字符数长度限制;

表单类型:TextInput<input type="text" ...>

DateField

DateField(auto_now=False, auto_now_add=False,**options):以 datetime.date实例表示的日期

含有两个可选参数:auto_nowauto_now_add

auto_now:该值为True时,每次在保存数据对象时,自动设置该字段为当前时间,也可以理解为自动更新最后一次修改时间

auto_now_add:该值为True时,该字段设置在第一次数据对象创建时,可以记录当前字段创建的时间值

注意:避免矛盾,auto_nowauto_now_adddefault不能同时出现,一个字段属性只能有其中一条设置,当设置了auto_now,或auto_now_add时,也会让该字段默认具有blank=True(字段可以为空)属性

表单类型:TextInput<input type="text" ...>

DatetimeField

DatetimeField(auto_now=False, auto_now_add=False,**options):以datetime.datetime实例表示的日期和时间

DateField具有相同的字段属性

DecimalField

DecimalField(max_digits=None,decimal_places=None, **options):以Decimal实例标示的十进制浮点数类型

含有两个可选参数:max_digitsdecimal_places

max_digits:位数总数,包括小数点后的位数,必须大于decimal_places参数

decimal_places:小数点后的数字数量,精度

表单类型:TextInput<input type="text" ...>

EmailField

EmailField(max_length=254, **option)CharField子类,表示Email字段,并会检查是否为合法邮箱地址

默认参数:max_length,表示邮箱地址长度,默认为254

表单类型:TextInput<input type="text" ...>

FloatField

FloatField(**options):使用float实例来表示的浮点数

表单类型:TextInput<input type="text" ...>

IntegerField

IntegerField(**options):一个整数,范围由-21474836482147483647

GenericIPAddressField

GenericIPAddressField(protocol=both, unpack_ipv4=False, **options):一个IPV4或IPV6地址的字符串

默认参数:protocolunpack_ipv4

protocol:IP协议,ipv4或ipv6,默认both为全选

unpack_ipv4:解析IP地址,只有当协议为both时才可以使用

表单类型:TextInput<input type="text"...>

SlugField

SlugField(max_length=50, **option):只包含字母、数字、下划线的字符串,常用来表示连接中的path部分或者一些其他短标题类型数据

TextField

TextField(**options):大文本字段

表单类型:Textarea<textarea>...</textarea>

URLField

URLField(max_length=200, **options)CharField的子类,存储URL的字段

表单类型:TextInput<input type="text"...>

字段属性

以上所介绍的字段,均支持以下属性

null

如果该值为True,Django将在数据库中将控制存储为NULL

字符串字段CharField与TextField要避免使用null,因为空值字符串将存储空字符串(""),而不是null值。

对于字符串类型的数据字段,大多数情况下,django使用空字符串代表空值

blank

如果该值为True,则在验证时该字段值可以为空;

null为数据库存储层面可以为空,而blank为表单验证层面可以填写空值

choices

一个二元组的列表或元组;

元组中第一个值为真正在数据库中存储的值,第二个值为该选项的描述

该值一旦被设定,表单样式会显示选择框,而不是标准的文本框,选择框内的选项为choices中的元组

class TestTable(models.Model):
	CHAR_CHOICE = [
        ('H',"非常苦难"),
        ('M',"中等难度"),
        ('S',"非常简单"),
	]
	choicechar = modesl.CharField(max_length=1,choices=CHAR_CHOICE)
  • choices字段也支持分类的写法
CHAR_CHOICE = [
	('A',
		(
			('H',"Hard"),
		)
	),
	('B',
		(
			('M',"Medium"),
		)
	),]

分类的名称作为元组中的第一个值,

元组的第二个值为该分类下的一个新的二元组序列数据

db_column

数据库中用来表示该字段的名称,如果未指定,那么Django将会使用Field名作为字段名

db_index

当该值为True时,为该字段创建索引

default

该字段默认值,可以是一个值或是一个回调函数

当是一个函数对象时,在创建新对象时,函数调用

editable

如果设置该值为False,那么这个字段将不允许被编辑

不会出现在admin后台界面下,以及其他ModelForm表单中,同时也会跳过模型验证

primary_key

设置该值为True时,该字段成为模型的主键字段,一个模型类同时只能有一个主键

如果一个表中不存在任意一个设置好的主键字段,django会自动设置一个自增AutoField字段来充当主键,该值可以用pkid方式获取。主键的设置还意味着,null=Falseunique=True

unique

如果该值为True,代表这个数据在当前的表中有唯一值

这个字段还会在模型层验证存储的数据是否唯一

unique的设置也意味着当前字段具备索引的创建

ManyToManyFieldOneToOneFieldFileField字段不可以使用该属性

verbose_name

对于字段的一个可读性更高的名称

如果没有设置该值,django将字段名中的下换线转换成空格,作为当前字段的数据库中名称

模型元属性

在模型类的Meta类中,可以提供一系列的元选项,可以方便对该模型类进行属性设置或约束等

class TestTable(models.Model):class Meta:
		ordering = [Fields]
abstract

代表当前模型类为抽象基类,不会创建真正的数据表,只是为了其他模型类继承使用

abstract = True
app_label

当模型类被定义在了其他app下,这个属性用来描述当前表属于哪个app应用

app_label = "MyApp"
db_table

当前模型类所对应的表名,未设置时,django默认将表名与app名由下划线组成,作为表名

需要注意这个表名为真实在数据库中所使用的,所以该元选项的使用应在数据表创建之前

如果在表已经存在的情况下去修改,会导致数据库内表与模型类表名不一致而查找不到报错

ordering

当前表中的数据存储时的排序规则,这是一个字段名的字符串,可以是一个列表或元组;

每一个字符串前可以使用"-“来倒序排序,使用”?"随机排序

ordering排序规则的添加,也会增加数据库的开销

ordering = ['-birthday', 'age']
#先按照birthday倒序排序,再按照age字段进行排序。
unique_together

用来设置表中的不重复字段组合

格式为一个元组,元组中的每个数据都是一个元组,用来描述不重复的组合字段

如果只处理单一字段组合,可以是一个一维的元组

联合约束

unique_together = (('name','phone'),)
verbose_name

一般设置该表展示时所用的名称,名称被自动处理为复数,字符串后加一个"s"

verbose_name_plural

verbose_name功能相同,但是不会自动在字符串后加"s"以表复数

设置表的复数名称

模型操作

在进行模型操作的学习之前,可以先创建一个测试的数据库模型类,如下所示

class Person(models.Model):
	name = models.CharField(max_length=10,verbose_name="姓名")
	age = models.IntegerField(verbose_name="年龄")
创建对象

django自带了一个数据库测试的shell工具

这是一个非常方便可以让我们对django代码进行测试的环境

可以直接通过python manage.py shell命令行管理工具来打开

实例save创建数据

通过模型类的关键词参数实例化一个对象来进行数据的创建

>>> from app.models import Person
>>> p1 = Person(name='张三',age=15)
>>> p1.save()

以上的代码,在为字段赋予值之后,通过实例的save函数进行该数据的保存

在数据库底层执行了SQL语句中的insert操作,并且,在我们显示调用save之前,django不会访问数据库,实例数据只存在于内存中

注意save函数没有返回值

create方法创建数据
>>> P1 = Person.objects.create(name='李四',age=20)

这条语句创建一条数据,并且返回一个数据在内存中的实例P1

之后可以通过这个实例字段P1对数据库中该条数据进行修改或删除操作

create 方法一步到位,save方式可以慢悠悠的赋予字段值,最后赋予结束再save

查找对象

接下来,我们将通过模型类中的管理器进行数据的查询;

管理器(Manager)是每一个模型类所具有的,默认名为objects

模型类通过模型类调用orm数据接口,其实就是在对数据表进行操作。

注意,具体的某一条数据无法访问这个管理器

all()

获取一个表中的所有数据,返回QuerySet数据对象

  • all_person = Person.objects.all()
    
filter(**kwargs)

返回一个包含数据对象的集合,满足参数中所给的条件

  • res = Person.objects.all().filter(age__lt=16)
    res = Person.objects.filter(age__lt=16)
    

我们在查询过程中,除了直接使用字段属性进行验证

还可以在字段名之后使用双下化线来标明更加详细的字段筛选条件(在下一节会有详细的字段筛选条件介绍),也叫做链式过滤

这也是为什么表单类字段不可以以下换线结尾的原因

exclude(**kwargs)

返回一个包含数据对象的集合,数据为不满足参数中所给的条件

filter()查询会始终返回一个结果集,哪怕只有一个数据。

但是有些时候,我们对于一些在数据表中的唯一数据进行查询时,可以使用更加合适的get方法


注意:创建结果集的过程不涉及任何数据库的操作,查询工作是惰性的,在上面的查询方式中,查询代码不会实际访问数据库,只有查询集在真正使用时,django才会访问数据库

get(**kwargs)

获取唯一单条数据

get获取数据只会返回一条匹配的结果,获取的数据只能在数据库中有一条

如果返回多个结果,会引发MultipleObjectsReturned异常

如果没有任何匹配到的结果也会引发DoesNotExist异常

  • Person.objects.get(pk=1)
    
order_by(*field)

默认情况下,数据表使用模型类中的Meta中指定的ordering选项进行排序

现在也可以通过使用order_by函数进行查询结果的排序,字段名称默认为升序,降序需要在字段名称前加“-”,代码如下:

  • Person.objects.order_by('age')   # 按照 age 字段升序排序
    
  • Person.objects.all().order_by('-age')   # 按照 age 字段降序排序
    
count()

返回数据库中对应字段的个数,并且该函数永远不会引发异常

 models.Person.objects.filter(age=20).count()
 Person.objects.count()

使用count函数时,还需要对数据表进行迭代访问

所以有时使用已生产好的结果集,通过len函数获取长度,这种方式效率会更高

count方法的调用会导致额外的数据库查询

values(*fields)

返回一个查询集结果,但是迭代访问时返回的是字典,而不是数据实例对象

models.Person.objects.all().values()
models.Person.objects.values()
修改对象

获取到对应的数据实例之后,通过.的方式访问数据实例中的属性,进行数据的字段修改

p = models.Person.objects.get(pk=1)
p.age = 21
p.save()

对过滤出的结果链式调用update()函数,这样的修改,类似批量修改,update函数会返回成功修改的个数

models.Person.objects.filter(age__gt=100).update(age=25)
# 将所有年纪小于100的人的年纪改为20
删除对象

对于普通的单表数据删除,获取到数据实例对象后调用内置的delete()函数即可

models.Person.objects.get(pk=1).delete()

需要注意的是,删除一条数据之后,默认占有的主键ID值并不会被下一个新插入的值所占用

比如 1,2,3,4;删除掉3之后,剩下:1,2,4;下一个值存储时,id是5,3不会被复用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值