Django——模型基础(单表)

Posted lymlike

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django——模型基础(单表)相关的知识,希望对你有一定的参考价值。

1.ORM

在MVC或者说MTV设计模式中,模型(M)代表对数据库的操作。但操作数据库需要专门的SQL语句,而Python程序员不是专业的DBA,写的SQL语句可能有点次,于是就有人想到用python语法来操作,这就是ORM。

ORM 即:对象—关系—映射(从https://www.cnblogs.com/huang-yc/p/9652935.html盗来一张图,顺便吹下这位博主!)

技术图片

简单又不太专业的说就是通过映射关系使得一个python语句对应一个SQL语句,这样python程序员无需关心ORM内部的细节,也不用很了解SQL语法,只要通过python就可以操作数据库了。

把代码敲一遍:

SQL语句

技术图片
# SQL的表

# 创建表:
CREATE TABLE employee(
    id INT PRIMARY KEY auto_increment,
    name VARCHAR(20),
    gender BIT default 1,
    birthday DATA,
    department VARCHAR(20),
    salary DECIMAL (8,2) unsigned
    );

# 表记录

# 添加一条表记录:
INSERT employee(name,gender,birthday,salary,department) VALUES("Alex",1,"1985-12-12",8000,"保洁部");

# 查询一条表记录:
SELECT * FROM employee WHERE age=24;

# 更新一条表记录:
UPDATE employee SET birthday="1989-10-10" WHERE id=1;

# 删除一条表记录:
DELETE FROM employee WHERE name="Alex"
View Code

Python语句

技术图片
# python的类

class Employee(models.Model):
    id=models.AutoField(primary_key=True)
    name=models.CharField(max_length=32)
    gender=models.Booleanfield()
    birthday=models.DateField()
    depatment=models.CharField(max_length=32)
    salary=models.DecimalField(max_digits=8,decimal_places=2)

# python类对象

# 添加一条表记录
emp=Employee(name="Alex",gender=True,birthday="1985-12-12",department="保洁部")
emp.save()

# 查询一条表记录
Employee.objects.filter(age=24)

# 更新一条表记录
Employee.objects.filter(id=1).update(birthday="1989-10-10")

# 删除一条表记录
Employee.objects.filter(name="Alex").delete()
View Code

 2.单表操作

 如前所说每个模型映射为一张数据库中的表,基本原则如下:

  • 每个模型在Django中的存在形式为一个Python类
  • 每个模型都是django.db.models.Model的子类
  • 模型的每个字段(属性)代表数据表的某一列
  • Django将自动为你生成数据库访问API

2.1创建表

跟上面一样,上代码:

from django.db import models

# Create your models here.


class User(models.Model):
    username = models.CharField( max_length=20, unique=True)
    password = models.CharField( max_length=256)
    email = models.EmailField()
    create_time = models.DateTimeField( auto_now_add=True)

2.2常用字段和参数

字段是模型中最重要的内容之一,也是唯一必须的部分。字段在Python中表现为一个类属性,体现了数据表中的一个列。字段决定数据库中对应列的数据类型,每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。这里就列出一些常用的或常见的。

常见字段:

类型                     说明

AutoField       # 一个自动增加的整数类型字段。通常你不需要自己编写它,Django会自动帮你添加字段:id = models.AutoField(primary_key=True),这是一个自增字段,从1开始计数。如果你非要自己设置主键,那么请务必将字段设置为primary_key=True。Django在一个模型中只允许有一个自增字段,并且该字段必须为主键!
BooleanField      # 布尔值类型。默认值是None。在HTML表单中体现为CheckboxInput标签。如果要接收null值,请使用NullBooleanField。
CharField       # 字符串类型。必须接收一个max_length参数,表示字符串长度不能超过该值。默认的表单标签是input text。最常用的filed,没有之一!
CommaSeparatedIntegerField       # 逗号分隔的整数类型。必须接收一个max_length参数。常用于表示较大的金额数目,例如1,000,000元。
DateField        # class DateField(auto_now=False, auto_now_add=False, **options)日期类型。一个Python中的datetime.date的实例。在HTML中表现为TextInput标签。在admin后台中,Django会帮你自动添加一个JS的日历表和一个“Today”快捷方式,以及附加的日期合法性验证。两个重要参数:(参数互斥,不能共存) auto_now:每当对象被保存时将字段设为当前日期,常用于保存最后修改时间。auto_now_add:每当对象被创建时,设为当前日期,常用于保存创建日期(注意,它是不可修改的)。设置上面两个参数就相当于给field添加了editable=False和blank=True属性。如果想具有修改属性,请用default参数。例子:pub_time = models.DateField(auto_now_add=True),自动添加发布时间。
DateTimeField       # 日期时间类型。Python的datetime.datetime的实例。与DateField相比就是多了小时、分和秒的显示,其它功能、参数、用法、默认值等等都一样。
DecimalField        # 固定精度的十进制小数。相当于Python的Decimal实例,必须提供两个指定的参数!参数max_digits:最大的位数,必须大于或等于小数点位数 。decimal_places:小数点位数,精度。 当localize=False时,它在HTML表现为NumberInput标签,否则是text类型。例子:储存最大不超过999,带有2位小数位精度的数,定义如下:models.DecimalField(..., max_digits=5, decimal_places=2)。
DurationField     # 持续时间类型。存储一定期间的时间长度。类似Python中的timedelta。在不同的数据库实现中有不同的表示方法。常用于进行时间之间的加减运算。但是小心了,这里有坑,PostgreSQL等数据库之间有兼容性问题!
EmailField     # 邮箱类型,默认max_length最大长度254位。使用这个字段的好处是,可以使用DJango内置的EmailValidator进行邮箱地址合法性验证。
FileField    # class FileField(upload_to=None, max_length=100, **options)上传文件类型,   http://www.liujiangblog.com/course/django/95
FilePathField     # 文件路径类型     http://www.liujiangblog.com/course/django/95
FloatField        # 参考整型     http://www.liujiangblog.com/course/django/95
ImageField     # 图像类型     http://www.liujiangblog.com/course/django/95
IntegerField      # 整数类型,最常用的字段之一。取值范围-2147483648到2147483647。在HTML中表现为NumberInput标签。
GenericIPAddressField         # class GenericIPAddressField(protocol=‘both‘, unpack_ipv4=False, **options)[source],IPV4或者IPV6地址,字符串形式,例如192.0.2.30或者2a02:42fe::4在HTML中表现为TextInput标签。参数protocol默认值为‘both’,可选‘IPv4’或者‘IPv6’,表示你的IP地址类型。
NullBooleanField      #   类似布尔字段,只不过额外允许NULL作为选项之一。
TextField      # 大量文本内容,在HTML中表现为Textarea标签,最常用的字段类型之一!如果你为它设置一个max_length参数,那么在前端页面中会受到输入字符数量限制,然而在模型和数据库层面却不受影响。只有CharField才能同时作用于两者。
TimeField         # 时间字段,Python中datetime.time的实例。接收同DateField一样的参数,只作用于小时、分和秒。
URLField        # 一个用于保存URL地址的字符串类型,默认最大长度200。
UUIDField      #  用于保存通用唯一识别码(Universally Unique Identifier)的字段。使用Python的UUID类。在PostgreSQL数据库中保存为uuid类型,其它数据库中为char(32)。这个字段是自增主键的最佳替代品,后面有例子展示。 

常用参数:

参数                说明

null    # 该值为True时,Django在数据库用NULL保存空值。默认值为False。
blank    # True时,字段可以为空。默认False。和null参数不同的是,null是纯数据库层面的,而blank是验证相关的,与数据库无关。所以要小心一个null为False,blank为True的字段接收到一个空值可能会出bug或异常。
choices       # 用于页面上的选择框标签,需要先提供一个二维的二元元组,第一个元素表示存在数据库内真实的值,第二个表示页面上显示的具体内容。
default   # 字段的默认值,可以是值或者一个可调用对象。如果是可调用对象,那么每次创建新对象时都会调用
primary_key     # 如果你为某个字段设置了primary_key=True,则当前字段变为主键,并关闭Django自动生成id主键的功能。primary_key=True隐含null=False和unique=True的意思。一个模型中只能有一个主键字段!
db_index         # 该参数接收布尔值。如果为True,数据库将为该字段创建索引。
unique      # 设为True时,在整个数据表内该字段的数据不可重复。
 # 注意:对于ManyToManyField和OneToOneField关系类型,该参数无效。
 # 注意: 当unique=True时,db_index参数无须设置,因为unqiue隐含了索引。

verbose_name    # 为字段设置一个人类可读,更加直观的别名。

2.3settings配置

技术图片
import pymysql
pymysql.install_as_MySQLdb()

DATABASES = {
    default: {
        ENGINE: django.db.backends.mysql,
        NAME: myblog,      # 数据库名
        USER: root,          # 数据库的用户名
        PASSWORD: pwd,      # 数据库密码
        HOST: ‘‘,        # 主机IP,默认本机
        PORT: ‘‘         # 主机端口,默认“3306”
    }
}
View Code

要注意:NAME即数据库的名字,在mysql连接前该数据库必须提前手动创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建 USER和PASSWORD分别是数据库的用户名和密码。

 最后通过两条数据库迁移命令即可在指定的数据库中创建表:

python manage.py makemigrations
python manage.py migrate

2.4记录表的增、删、改

增:两种方式

# 方式一:create
user = models.User.objects.create(username="Alex",password="pwd",email="alex@163.com")      # create方法的返回值即为新插入表的名为Alex的对象

#方式二:save
user = models.User(username="Alex",password="pwd",email="alex@163.com")
user.save()

删:

删除对象使用的是对象的delete()方法。

user.delete()

你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。
例如,下面的代码将删除 pub_date 是2005年的Article对象:

models.Article.objects.filter(pub_date__year=2005).delete()

当Django删除一个对象时,它默认使用SQL的ON DELETE CASCADE约束,也就是说,任何有外键指向要删除对象的对象将一起被删除。例如:

u = models.User.objects.get(pk=1)
# 下面的动作将删除该条Blog和所有的它关联的Article对象
u.delete()

这种级联的行为可以通过的ForeignKey的on_delete参数自定义,如果不想级联删除,就可以设置on_delete为其他方式,如:

user = models.ForeignKey(to=User, on_delete=models.SET_NULL, blank=True, null=True)

注意,delete()是唯一没有在Manager管理器上暴露出来的方法。这是刻意设计的一个安全机制,用来防止你意外地请求类似models.User.objects.delete()的动作,而不慎删除了所有的条目。如果你确实想删除所有的对象,你必须明确地请求一个完全的查询集,像下面这样:

models.User.objects.all().delete()

改:

使用update()方法可以批量为QuerySet中所有的对象进行更新操作。

models.User.objects.filter(name__contents="Alex").update(name="Eric")

要注意的是update()方法会直接转换成一个SQL语句,并立刻批量执行。它不会运行模型的save()方法,或者产生pre_savepost_save信号

2.5记录表的查询

查询的API较多,所以放在最后,而且这里仅列出少量常用API

方法                说明

all()           # 获取所有对象
filter(**kwargs)           # 根据条件过滤查询对象
exclude(**kwargs)         # 排除满足条件的对象
order_by(*fileld)         # 对查询集进行排序
reverse()           # 反向排序
values(*fileld)             # 返回一个特殊的的QuerySet,这个QuerySet中不是一个个models的实例化对象,而是根据*fileld查询的具体值的字典
values_list(*fileld)       # 这个和values()类似,但是它返回的是元组,而不是字典
distinct()         # 从返回的查询集中剔除重复记录

# 注意上面的API返回的是QuerySet对象,下面的API不返回QuerySet对象

get()      # 获取单个对象
first()       # 获取查询到的第一个对象
last()       # 获取查询到的最后一个对象
count()      # 统计查询的QuerySet中对象个数
exists()        # 判断QuerySet中是否有对象,有返回True,无返回Flase


另:使用类似Python对列表进行切片的方法可以对QuerySet进行范围取值
models.User.objects.all()[:5]      # 返回前5个对象
models.User.objects.all()[5:10]    # 返回第6个到第10个对象
 # 不支持负索引!

字段查询是指如何指定SQL WHERE子句的内容。它们用作QuerySet的filter(), exclude()和get()方法的关键字参数

常用字段查询参数(双下滑线的模糊查询):

参数                 说明

contains       # 区分大小写的包含匹配
icontains       # 不区分大小写的包含匹配
in             # 在...中的匹配
gt / gte            # 大于 / 大于等于
lt / lte            # 小于 / 小于等于
range            # 范围匹配
date            # 日期匹配
year / month / day          # 年 / 月 / 日    匹配
startswith / istartswith      # 区分大小写/不区分大小写     以...开头匹配
endswith / iendswith        # 区分大小写/不区分大小写     以...结尾匹配


用法

models.User.objects.filter(id__gt=5)
models.User.objects.filter(id__range=[10,15])
models.User.objects.filter(name__contains="Alex")
models.User.objects.filter(name__icontains="ALEX")
models.User.objects.filter(name__startswith="E")
models.User.objects.filter(create_time__year=2016)

 

以上是关于Django——模型基础(单表)的主要内容,如果未能解决你的问题,请参考以下文章

Django——模型基础(单表)

Django基础之django ORM单表操作

Django基础之django ORM单表操作

Django ORM - 单表实例

Django基础之模型(models)层

django目录