Django中实现了一套操作数据库的强大API,今天博主想按照数据库学习的常规思路来分享一下如何在Django中实现一些常规的数据库操作,话不多说,请看下文的干货。
Django中支持PostgreSQL、SQLite3、MySQL和Oracle四中数据库,默认的数据库为SQLite3,例如使用django-admin startproject mysite
命令新建一个project后可以看到其中的数据库配置为SQLite3:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
倘若要使用其他数据库则需要加上其他参数,下面给出参数配置示例:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '数据库的名称',
'USER': '换数据库的账户名',
'PASSWORD': '连接数据库的密码',
'HOST': '数据库服务器的IP,若数据库在本地直接用127.0.0.1即可',
'PORT': '数据库对应的端口,MySQL为3306'
}
}
在django中倘若需要创建关系表,需要先创建对应的模型类,模型类需要继承django.db.models.Model
类,模型类需要定义在models.py
文件中。这里我在mysite项目中先利用python manage.py startapp sams
创建了一个新的app,然后该app的models.py
文件中定义了学生Student,课程Lectures,成绩Score三个模型类,示例代码如下:
class Student(models.Model):
stu_num = models.CharField(max_length=10,primary_key=True)
name = models.CharField(max_length=50)
SEX = (
('female','女'),
('male','男')
)
sex = models.CharField(max_length=10,choices=SEX)
birth_date = models.DateField()
class Lectures(models.Model):
class_id = models.CharField(max_length=10,primary_key=True)
class_name = models.CharField(max_length=30)
teacher = models.CharField(max_length=30)
class Score(models.Model):
stu_num = models.ForeignKey(Student,on_delete=models.CASCADE,max_length=10)
class_id = models.ForeignKey(Lectures,on_delete=models.CASCADE,max_length=10)
mark = models.FloatField()
class Meta:
unique_together = ("stu_num","class_id")
constraints = [
models.CheckConstraint(check=models.Q(mark__range=(0,100)),name='mark_check')
]
保存上述代码后依次运行命令python manage.py makemigrations
和python manage.py migrate
就可以在MySQL中创建好相应的关系表如下图所示:
在完成上述操作后,便可以利用Django提供的API对数据库表进行操作了,除了采用这种方式,Django还提供了管理后台来进行关系表的管理,具体做法是在app的admin.py
文件中登记创建的表,示例代码如下:
from django.contrib import admin
from sams.models import Student,Lectures,Score
# Register your models here.
admin.site.register(Student)
admin.site.register(Lectures)
admin.site.register(Score)
然后运行python manage.py createsuperuser
命令创建管理员账户,之后便可运行python manage.py runserver
命令并打开http://127.0.0.1:8000/admin/链接对数据库表进行操作了,下面是管理员界面的截图:
在利用Django的API进行DML前,需要运行python manage.py shell
进入命令交互界面,首先需要导入三个要操作的模型类:
from sams.models import Student,Score,Lectures
首先是往关系表中插入数据,常用的方法有两种:
示例代码如下:
# 向Student表插入数据
Student(stu_num='2017000001',name='张三',sex='男',birth_date='1999-01-12').save()
Student.objects.create(stu_num='2017000001',name='张三',sex='男',birth_date='1999-01-12')
# 向Lectures表插入数据
Lectures(class_id='10001',class_name='操作系统',teacher='赵宇').save()
Lectures.objects.create(class_id='10001',class_name='操作系统',teacher='赵宇')
# 向Score表插入数据
Score(stu_num=Student.objects.get(stu_num='2017000001'),class_id=Lectures.objects.get(class_id='10001'),mark=90).save()
Score.objects.create(stu_num=Student.objects.get(stu_num='2017000001'),class_id=Lectures.objects.get(class_id='10001'),mark=90)
然后是查询操作,Django中常用的查询方法以及含义如下表所示:
Django中的查询方法 | 功能 | 等价的SQL语句 |
---|---|---|
模型类.objects.all() | 获取关系表中所有的行,结果返回一个QuerySet | SELECT * FROM table_name |
模型类.objects.filter() | 按条件过滤关系表中指定的行,结果返回一个QuerySet | SELECT * FROM table_name WHERE … |
模型类.objects.values()/模型类.objects.values_list() | 选择关系表中指定的字段,并以字典/列表的格式返回 | SELECT col1, … ,coln FROM … |
方法的示例代码如下:
Lectures.objects.all().values()
#
Score.objects.filter(stu_num='2017000002',class_id='10003').values()
#
Student.objects.filter(birth_date__range=(datetime.date(1998,1,1),datetime.date(1999,5,6))).values()
#
for stu in Student.objects.values('stu_num','name','birth_date'):print(stu)
"""
{'stu_num': '2017000001', 'name': '张三', 'birth_date': datetime.date(1999, 1, 12)}
{'stu_num': '2017000002', 'name': '李强', 'birth_date': datetime.date(1999, 7, 14)}
{'stu_num': '2017000003', 'name': '李娜', 'birth_date': datetime.date(2000, 12, 15)}
{'stu_num': '2017000004', 'name': '张飞', 'birth_date': datetime.date(1997, 10, 13)}
{'stu_num': '2017000005', 'name': '关羽', 'birth_date': datetime.date(1996, 3, 24)}
{'stu_num': '2017000006', 'name': '赵云', 'birth_date': datetime.date(1999, 8, 8)}
"""
在Django中通过order_by()
函数可以实现排序,倘若要根据多个字段排序,则字段间需要用逗号分隔,若要将排序结果倒序则还需要调用reverse()
函数,示例代码如下:
for stu in Student.objects.order_by('birth_date').values().reverse():print(stu)
"""
{'stu_num': '2017000003', 'name': '李娜', 'sex': 'female', 'birth_date': datetime.date(2000, 12, 15)}
{'stu_num': '2017000006', 'name': '赵云', 'sex': 'male', 'birth_date': datetime.date(1999, 8, 8)}
{'stu_num': '2017000002', 'name': '李强', 'sex': 'male', 'birth_date': datetime.date(1999, 7, 14)}
{'stu_num': '2017000001', 'name': '张三', 'sex': '男', 'birth_date': datetime.date(1999, 1, 12)}
{'stu_num': '2017000004', 'name': '张飞', 'sex': 'male', 'birth_date': datetime.date(1997, 10, 13)}
{'stu_num': '2017000005', 'name': '关羽', 'sex': 'male', 'birth_date': datetime.date(1996, 3, 24)}
"""
在Django中包含三种数据库关联关系,即:
关联类型 | 实现方法 | 示例 |
---|---|---|
多对一关联 | 通过django.db.models.ForeignKey 类定义 |
学生和课程成绩间的关系 |
多对多关联 | 通过django.db.models.ManyToManyField 类定义 |
配料与披萨之间的关系 |
一对一关联 | 通过django.db.models.OneToOneField 类定义 |
人与身份证号的关系 |
而Django提供了有关联的关系表间的双向访问途径,倘若一个模型类Class1的某个属性是另一个模型类Class2,则Class1可以通过该属性访问到其所关联的外部对象,同样的,Class2的实例也能访问到该模型类中与之关联的实例,方法是通过classname_set
属性,其中classname为定义Class1的类名,实例代码如下:
stu1 = Student.objects.get(stu_num='2017000001')
score1 = Score.objects.get(stu_num='2017000001',class_id='10002')
score1.stu_num.name
# '张三'
stu1.score_set.all().values()
#
在Django中分组聚合(group by + aggerate)是通过values()
方法和annotate()
方法实现的,其中values()
方法用来选择分组的字段,而annotate()
方法则用来指定聚合函数,示例代码如下:
for s in Score.objects.values('stu_num').annotate(stu_avg_score=Avg('mark')):print(s['stu_num'],s['stu_avg_score'])
"""
2017000001 92.33333333333333
2017000002 73.66666666666667
2017000003 84.66666666666667
2017000004 58.666666666666664
2017000005 83.33333333333333
2017000006 96.66666666666667
"""
Django中提供了类似于python列表的索引方式,索引也是从0开始,示例代码如下:
Student.objects.all()[0:3]
# , , ]>
Student.objects.all()[0:5:2]
"""
[,
,
]
"""
Student.objects.all()[4]
#
Django中数据库的操作还有很多,但常规的操作都已经在上文中展示了,其余的就需要根据自己的需求自己去探索了。以上便是本文的全部内容,要是觉得不错的话就点个赞或关注一下博主吧,你们的支持是博主继续创作的不解动力,当然若是有任何问题也敬请批评指正!!!