Django模型使用详解 VS choinces的用法
模型字段
字段类型:
-
AutoField:一个自增的IntegerField,想要自定义主键,那么primary_key必填。一般不直接使用,因为django会自动为每一张表添加自增主键(primary_key) -
CharField:用来存储字符串,必须指定范围(在254个字符之内),如果存储大文本字符串(超过254个字符),应当用 TextField - 可存储任意长度的文本,对应数据库类型为 lonetext。如果不设置max_length, 会报错。 -
DateField:使用Python的datetime.date实例保存的日期,记录年月日,在映射数据库中也是date类型,使用这个字段类型可以传递以下几个参数: -
auto_now = True: 每次保存对象时,自动设置该字段为当前时间(可用于修改字段); -
auto_now_add = True: 对象第一次被创建时自动设置当前的时间。需要注意的是:自动保存的时间的时区使用的是默认时区(可用于创建字段)。
-
-
DateTimeField:使用Python的datetime.datetime实例表示日期和时间, 映射到数据库中是datetime类型。 -
TextField:存储大字符串(大于254个字符的),映射到数据库为:longtext类型。 -
BigIntegerField:64位整型,从-2^63 ( -9223372036854775808) 到 2^63-1 (9223372036854775807)。 -
IntegerField:整型,值区间为:-2147483648 —— 2147483647。 -
BinaryField :存储二进制的字段,只支持bytes赋值。 -
BooleanField :存储True 或 False,在数据库层面是:tinyint类型,如果没有指定默认值,默认值为None。如果此字段有可能为null值,你必须把类型设置为 NullBooleanField,否则,将会报错。 -
FloatField:存储浮点数的字段类型,用python的一个Float实例来表示浮点数。 -
UUIDField:用来存储UUID的字段。使用的是python的UUID类。 -
ForeignKey:多对一关系。 -
ManyToManyField:多对多关系。 -
OneToOneField:一对一关联关系。 -
DecimalField:用于计算价格或者金融项目存储金额时,所用的字段类型:表示固定精度的十进制数的货币字段。两个必填参数: -
max_digits : 数字允许的做大位数; -
decimal_places: 小数的最大位数。 -
如:要存储的数字为:最大长度为4位数,小数点后2位小数,models.DecimalField( max_digits=4, decimal_places=2 )。
-
参数说明
-
null = True - 数据库字段是否可为空,True可为空,默认情况下为:False不可为空。 -
blank = True - django的Admin中添加数据时是否允许为空值。与null的区别为:null是一个纯数据库级别的,而blank是表单验证级别的。 -
primary_key = False - 主键,对AutoField类型的字段设置主键后,就会代替原来自增id列。如果您没有为模型中的任何字段指定primary_key=True, Django将自动添加一个IntegerField来保存主键,所以您不需要在任何字段上设置primary_key=True,除非您想要覆盖默认的主键行为。 -
auto_now= True - 每次保存或添加都会创建当前时间(可用于修改/编辑时间字段) -
auto_now_add = True- 每次保存或添加都会保存第一次创建的时间(可用于创建时间字段) -
max_length - 定义字符串最大长度。 -
default - 给字段定义默认值,注意:如果你想设置一个默认值,前提需要设置null=True。如果没传值,没设置null=True,即使你设置了默认值存到数据库中也是null。 -
unique = True - 不允许重复,如:用户密码等等。 -
auto_create = False - 自动创建。 -
upload_to - 文件上传指定的目录。 -
db_column - 可更改数据库中字段的名字,如果没有设置此字段,那么将会使用模型中属性的名字。 -
choices:一系列二元组,用作此字段的选项。如果提供了二元组,默认表单小部件是一个选择框,而不是标准文本字段,并将限制给出的选项。
choinces的用法
class TestModel(models.Model):
GENDER_CHOICE = (
('M', '男'),
('F', '女'),
)
name = models.CharField(max_length=60)
gender = models.CharField(max_length=1, choices=GENDER_CHOICE)
一对多
class Author(models.Model):
"""新闻发布者表,机构表,作者表"""
# 这张表会被django自动创建
# 这个字段对应MySQL里面的varchar(70)类型
name = models.CharField(max_length=70)
# 自动创建:article_set
def __str__(self):
"""这个方法,在print(reporter)的时候,会被调用,
返回值是什么,打印的就是什么"""
return self.name
class Article(models.Model):
"""文章表"""
# 发布日期
pub_date = models.DateField()
# 标题
title = models.CharField(max_length=200)
# 内容
content = models.TextField()
# 作者,外键关联作者表
author = models.ForeignKey(Author, on_delete=models.CASCADE)
def __str__(self):
return self.title
多对多
模型的创建
class Teacher(models.Model):
name = models.CharField(max_length=72)
class Student(models.Model):
name = models.CharField(max_length=72)
teachers = models.ManyToManyField(Teacher)
多对多关系的本质,实际上是让一张第三方表,映射了两张表的关联关系。在Django的实现中,也是这样的,只不过Django可以帮我们隐藏映射的细节,我们不需要关心具体的实现,只需要在模型中简单的声明。但是,Django实际上,也会在底层默认帮我们创建第三张表。
在第三张表中,其实最核心的就是有一个表1的外键和一个表2的外键,通过这两个外键的值,指定了两张表的关联关系。
多对多的关系如何新增数据
from index.models import Teacher
lls = Teacher.objects.create(name="李老师")
zls = Teacher.objects.create(name="张老师")
from index.models import Student
zs = Student.objects.create(name="张三")
zs.teachers.add(lls)
zs.save()
多对多的关系,主表如何反向添加多对多关联关系
from index.models import Teacher
lls = Teacher.objects.create(name="李老师")
zls = Teacher.objects.create(name="张老师")
from index.models import Student
zs = Student.objects.create(name="张三")
zs.teachers.add(lls)
zs.save()
zls.student_set.add(zs)
zls.save()
一对一
一对一模型的创建。
class User(models.Model):
name = models.CharField(max_length=72)
class UserDetail(models.Model):
address = models.CharField(max_length=255)
intro = models.CharField(max_length=255)
user = models.OneToOneField(to=User, on_delete=models.CASCADE)
基本的用法和外键类似。
from index.models import User, UserDetail
zs = User.objects.create(name='张三')
zs.id
zsd = UserDetail.objects.create(address='', intro='', user=zs)
zsd
zsd.user.name
zs.userdetail.address
模型元数据
模型元数据通过一个叫做Meta的内部类就定义,一般用来解释和说明这个模型的表层级的描述信息。通常可以包括:
-
ordering:是一个数组,决定查询结果的排序规则,默认是根据ID升序。 -
verbose_name和 verbose_name_plural:这两个字段一个决定单词是单数的时候在后台管理界面中该表格的显示名字,一个决定单词是复数的时候该表格在后台管理界面中的名字。其值是一个字符串,通常设置为一样的。 -
db_table:其值是一个字符串,决定的是这个模型在数据库中对应的表名是什么。默认是“应用名小写_模型名小写”。在其他的系统中,博客表一般喜欢叫做blog,但是在Django中,默认可能是blog_blog,所以如果是和别的团队配合开发的化,这个属性的作用将会非常巨大。
模型方法
str重写模型字符串
class User(models.Model):
name = models.CharField(max_length=72)
def __str__(self):
return f"<User {self.id}:{self.name}>"
save保存
save方法主要用来新增和修改。如果这个对象不存在,则表示新增,如果已存在则表示修改。基本用法是查询或者创建一个模型的实例对象,对其属性新增赋值或者修改,然后调用save方法进行保存。
from index.models import User
zs = User(name='张三')
zs.save()
create创建
create方法比较少用,一般都用save。create有一个很大的缺点,就是一旦参数传错了,会直接崩溃。但是create也有优点,那就是能够用一行代码解决新增的问题。示例代码:
# 基本用法
User.objects.create(name='李四')
# 通过字典创建
data = {'name': '王五'}
User.objects.create(**data)
all查询所有
all是最简单最通用的查询方法,实际上他不会真的把数据立即取出来,除非我们将其传递给前端或者对其进行遍历。所以,理论上,我们在执行all查询的时候,内存不会有明显的增加,只有在使用的时候,才可能会突然增长。底层实际上是基于一个生成器原理,生成查询语句,返回了一个可迭代对象,但是呢又没有真正的把数据存储在内存中,而是给我们提供了一种获取所有数据的方式。使用方法如下:
# 基本用法
User.objects.all()
# 通过切片取前两条
User.objects.all()[:2]
分页查询:
# 每页2条,取第1页
User.objects.all()[0:0+2]
# 每页2条,取第2页
User.objects.all()[2:2+2]
firs取第一条
User.objects.first()
last取最后一条
User.objects.last()
order_by排序
# 根据ID升序
User.objects.all().order_by("id")
# 根据ID降序
User.objects.all().order_by("-id")
get根据字段查询单个
# 根据ID查询
User.objects.get(id=1)
# 根据字段查询
# 注意:如果返回个数大于会抛出异常
User.objects.get(name='张三')
delete删除
# 根据get删除
User.objects.get(name='李四').delete()
# 删除第一个
User.objects.first().delete()
# 删除最后一个
User.objects.last().delete()
# 根据ID删除
User.objects.get(id=1).delete()
THE END