Django 模型
模型是MVC架构中访问数据的模块,Django的模型对各种数据库提供了很好的支持。这里以MySQL为例介绍Django的模型。
使用模型#
启用数据库支持#
在项目的 settings.py 文件中找到 DATABASES 配置项, 根据数据库配置信息:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'testuser',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
}
}
Django的目录结构包括Project和App两层, 同一个Project下的不同App共享Project的数据库连接。
settins.py中INSTALLED_APPS用来维护Project中的APP包括自定义APP和插件APP.
必须在INSTALLED_APPS中添加APP的名称字符串,该APP才可以使用模型。
实现模型类#
ORM (Object Relational Mapping,对象关系映射)将程序员定义的类映射为数据表。Django提供了优秀的ORM实现。
一般在model.py中定义相关模型,模型类需要继承django.db.models.Model
。
类名代表数据表名,类中的字段代表数据表中的字段, 类的一个实例表示一条数据记录。
将primary_key关键字参数置为True,即可添加主键约束。
在未指定primary_key的情况下,Django会默认创建一个id
自增字段作为主键。
示例:
from django.db import models
class Account(models.Model):
account_name = models.CharField(max_length=20)
account_id = models.IntegerField(primary_key=True)
balance = models.DecimalField(max_digits=2, decimal_places=2)
同步数据库#
manage.py中提供了同步数据库的命令,在项目目录下依次执行命令
python manage.py makemigrations
python manage.py migrate
在修改数据库结构后只需要重新同步数据库即可。
终端交互历史:
E:\workspace\Django\ThirdDjango>python manage.py makemigrations
Migrations for 'ModelDjango':
0001_initial.py:
- Create model Account
E:\workspace\Django\ThirdDjango>python manage.py migrate
Operations to perform:
Apply all migrations: admin, ModelDjango, contenttypes, auth, sessions
Running migrations:
Rendering model states... DONE
Applying ModelDjango.0001_initial... OK
注意在Django1.7及以后版本中python manage.py syncdb
已被移除。
字段#
django.db.models
模块中定义了大量标准字段,常用的包括:
CharField#
SQL中的varchar类型,max_length关键字参数指定长度。
account_name = models.CharField(max_length=20)
IntegerField#
整数字段
account_id = models.IntegerField(primary_key=True)
DecimalField#
decimal类型,max_digits指定总位数, decimal_places指定小数位数
balance = models.DecimalField(max_digits=2, decimal_places=2)
AutoField#
从1开始自增的整型字段
id = models.AutoField()
DateTimeField#
SQL中的datetime类型, 使用Python中的datetime.datetime类型表示
使用下面的构造函数构造一个datetime对象
datetime.datetime (year, month, day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo]]]]])
关于Python的datetime模块详情可以参考这篇博客.
可以使用auto_now=True
关键字参数使实例每次执行save()时该字段自动保存save时间,不允许手动赋值。
更多标准字段请见Django Book:
关系字段#
关系字段用于保存数据表之间的关系,包括ForeignKey, ManyToManyField等。
修改数据#
在建立模型后Django提供了一系列API进行数据操作,取代原始SQL语句。
添加数据记录#
实例化模型类,用关键字参数对各列赋值,并调用对象的save()方法将对象写入数据库。
示例:
account_john = Account(account_name='john', accouunt_id='123', balance=0);
account_john.save()
save()方法没有返回值,在显式调用save()之前不会访问数据库.Account实例的字段是可以直接访问或修改的.
或者调用model_class.objects.create()
Account.objects.create(account_name='john', accouunt_id='123', balance=0)
或者使用:
Account.objects.get_or_create(account_name='john', accouunt_id='123', balance=0)
删除数据记录#
调用数据记录的delete()方法可以删除数据记录。
account.delete()
查询数据#
查询数据使用QuerySet API。 QuerySet是惰性执行的,创建Query Set不会访问数据库,只有在访问具体查询结果的时候才会访问数据库。
获取数据表的全部数据记录:
Account.objects.all()
返回值可以进行切片,但不支持负索引。或者使用:
Account.objects.get(field_name=val)
示例:
Account.objects.get(account_name='john')
或者使用过滤器查询多条记录:
-
Account.objects.filter(accounnt_name=val)
严格等于 -
Account.objects.filter(account_name__iexact=val)
忽略大小写 -
Account.objects.filter(account_name__contains=val)
名称中包含val -
Account.objects.filter(account_name__icontains=val)
忽略大小写,包含 -
Account.objects.filter(account_name__regex=val)
正则表达式 -
Account.objects.filter(account_name__iregex=val)
正则表达式,忽略大小写
与filter相反exclude用于返回不满足条件的查询结果。
Account.objects.exclude(account_name__contains=val)
filter与exclude可以进行链式查询
Account.objects.exclude(account_name__contains='john').exlucde(balance=0)
对于查询结果可以使用distinct()去重或者使用order_by(field)进行排序。
Account.objects.filter(account_name__regex=val).distinct()
Account.objects.filter(account_name__regex=val).oreder_by('balance')
使用reverse()方法可以反转结果集中的元素顺序,调用两次将会恢复原顺序。
从SQL 的角度,QuerySet和SELECT 语句等价,过滤器是像WHERE 和LIMIT 一样的限制子句。
使用原生SQL#
在模型查询API不够用的情况下,你可以使用原始的SQL语句。Django提供两种方法使用原始SQL进行查询。
一种是使用Model.objects.raw()方法,并进行原始查询并返回模型实例:
Account.objects.filter('select * from account')
这种方法为延迟执行,如:
for a in Account.objects.filter('select account_name, balance from account'):
print(a.account_name, a.account_id)
上述语句实际上执行了3次查询,account_name在raw中被查询, account_id在打印时被查询。
另一种是完全避开模型层,直接执行自定义的SQL语句。
from django.db import connection
def my_account_sql(self):
cursor = connection.cursor()
cursor.execute("UPDATE account SET account_id = 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
与其它数据库connection的用法非常类似。
编写原始的SQL语句时,应该格外小心。 每次使用的时候,都要确保转义了参数中任何用户可以控制的字符,以防受到SQL注入攻击。
作者:finley
出处:https://www.cnblogs.com/Finley/p/5296373.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 一个超经典 WinForm,WPF 卡死问题的终极反思
· ASP.NET Core - 日志记录系统(二)
· 支付宝事故这事儿,凭什么又是程序员背锅?有没有可能是这样的...
· 在线客服系统 QPS 突破 240/秒,连接数突破 4000,日请求数接近1000万次,.NET 多
· C# 开发工具Visual Studio 介绍
· 在 Windows 10 上实现免密码 SSH 登录
· C#中如何使用异步编程