Django中如何实现常规的数据库表操作

一.前言

Django中实现了一套操作数据库的强大API,今天博主想按照数据库学习的常规思路来分享一下如何在Django中实现一些常规的数据库操作,话不多说,请看下文的干货。

二.数据库连接

Django中支持PostgreSQLSQLite3MySQLOracle四中数据库,默认的数据库为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 makemigrationspython 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

4.1 增、删、改、查操作

首先是往关系表中插入数据,常用的方法有两种:

  • 先创建模型类的实例,然后运行该实例的save()方法
  • 直接调用模型类的create()方法

示例代码如下:

# 向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()获取关系表中所有的行,结果返回一个QuerySetSELECT * FROM table_name
模型类.objects.filter()按条件过滤关系表中指定的行,结果返回一个QuerySetSELECT * FROM table_name WHERE …
模型类.objects.values()/模型类.objects.values_list()选择关系表中指定的字段,并以字典/列表的格式返回SELECT col1, … ,coln FROM …

方法的示例代码如下:

Lectures.objects.all().values()
# <QuerySet [{'class_id': '10001', 'class_name': '操作系统', 'teacher': '赵宇'}, {'class_id': '10002', 'class_name': '计算机组成原理', 'teacher': '马强'}, {'class_id': '10003', 'class_name': 'C语言程序设计', 'teacher': '陈凡'}]>

Score.objects.filter(stu_num='2017000002',class_id='10003').values()
# <QuerySet [{'id': 6, 'stu_num_id': '2017000002', 'class_id_id': '10003', 'mark': 77.0}]>
Student.objects.filter(birth_date__range=(datetime.date(1998,1,1),datetime.date(1999,5,6))).values()
# <QuerySet [{'stu_num': '2017000001', 'name': '张三', 'sex': '男', 'birth_date': datetime.date(1999, 1, 12)}]>

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)}
"""

4.2 排序操作

在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)}
"""

4.3 多表关联

在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()
# <QuerySet [{'id': 1, 'stu_num_id': '2017000001', 'class_id_id': '10001', 'mark': 90.0}, {'id': 2, 'stu_num_id': '2017000001', 'class_id_id': '10002', 'mark': 89.0}, {'id': 3, 'stu_num_id': '2017000001', 'class_id_id': '10003', 'mark': 98.0}]>

4.4 分组聚合

在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
"""

4.5 限制返回的数据

Django中提供了类似于python列表的索引方式,索引也是从0开始,示例代码如下:

Student.objects.all()[0:3]
# <QuerySet [<Student: Student object (2017000001)>, <Student: Student object (2017000002)>, <Student: Student object (2017000003)>]>

Student.objects.all()[0:5:2]
"""
[<Student: Student object (2017000001)>,
 <Student: Student object (2017000003)>,
 <Student: Student object (2017000005)>]
"""

Student.objects.all()[4]
# <Student: Student object (2017000005)>

五.结语

Django中数据库的操作还有很多,但常规的操作都已经在上文中展示了,其余的就需要根据自己的需求自己去探索了。以上便是本文的全部内容,要是觉得不错的话就点个赞或关注一下博主吧,你们的支持是博主继续创作的不解动力,当然若是有任何问题也敬请批评指正!!!

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯曦巍峨

码文不易,有条件的可以支持一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值