应用中的models.py是用来和数据库连接时所使用的文件

models.py介绍

models使用了ORM技术
Object Relational Mapping 对象关系映射
将业务逻辑于sql进行了一个解耦合
就是不用写类似于insert sql语句来对数据进行处理
而是调用类似于objest.save()方法自动转换成sql语句
object.delete()
而且这些方法不管你连接的是mysql,sql,oracle等等数据库,统一用这些方法连接,而不是用
insert into 表名 等等等sql语句。
ORM可以理解为翻译机,不管你用什么数据库,都能帮你转换成合适的sql语句。

DDL

而作为关系型数据库,首先我们要DDL(Database Define Language 数据库模式定义语言/定义数据库)
在Django中通过models定义实现数据库表的定义

from django.db import models
#我们需要定义一个模型,要让Django系统承认这是一个模型,我们需要继承models.Model
class Student(models.Model):
    s_name = models.CharField(max_length=16)#默认最大长度为16
    s_age = models.IntegerField(default=1)#默认自带一岁

 

迁移模型至数据库

在我们定义完了模型之后需要将模型迁移至数据库中

步骤一:创建迁移文件

在终端输入:
python manage.py makemigrations
结果如下图:

我们的迁移文件在:应用里的migrations中

迁移文件内容如下:

from django.db import migrations, models


class Migration(migrations.Migration):#也是继承类型

    initial = True#初始化

    dependencies = [
    ]#依赖关系
#operations操作
    operations = [
        migrations.CreateModel(
            name='Student',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('s_name', models.CharField(max_length=16)),
                ('s_age', models.IntegerField(default=1)),
            ],
        ),
    ]

我们可以发现15行,在Django里会自动为模型补充id。
但是目前我们的数据库中还是没有这个模型的。

步骤二:映射迁移文件至数据库

终端输入:python manage.py migrate
也就是之前的迁移指令,运行之后才会将我们刚刚生成的迁移文件,将迁移文件映射到库中

可以观察到数据库中出现了刚刚的模型:

点击Data Editor查看表结构

可以在查看表结构的界面添加数据:

你也可以点击DDL查看如何创建表(创建表的sql语句)

创建语句如下:

(写到这里我就老泪纵横,之前苦苦学习mysql数据库一个月,sql语句学了一大堆,没想到现在是自动生成,裂开来了。。。)
但是我们可以看到第7行代码,之前我们default=1没有了,这不是出错,而是ORM帮我们做了一些事,有一些约束不是直接添加在表里的,而是在做操作时帮你做的。

用Django往数据库插入学生数据

two中添加路由(访问时的网址路径)

urlpatterns = [
    url('index/',views.index)
    url('addstudent/',views.add_student)
]

two中添加views函数(访问时响应内容和数据库操作)

用之前介绍的万能键快速建立add_student函数
在two.views中内容如下

from django.http import HttpResponse

from two.models import Student

def add_student(request):
    student = Student()#记得从models中导入Student模型
    student.s_name = '李四'
    student.save()   #数据库保存
    return HttpResponse("添加成功")

运行访问查看结果

2.0版本(多次添加不同名字的学生且返回添加者的姓名)

你还可以在学生姓名后面追加一个随机数,并且返回添加学生的具体姓名

def add_student(request):
    student = Student()#记得从models中导入Student模型
    student.s_name = '李四%d' % random.randrange(100)
    student.save()   #数据库保存
    return HttpResponse("添加成功 %s" % student.s_name )

这样我们多次访问网页就能多添加几个数据来观察结果
注意我们用到了random,需要导入random模块import random
image.png

3.0版本(显示学生列表)

我们在two.views中添加

def get_students(request):
    students = Student.objects.all()#objects是ORM提供学生操作的一个入口,抽象出来的操作入口
    for student in students:
        print(student.s_name)    
    return HttpResponse('student List')

这样可以访问two/getstudents/时,终端打印出学生列表

但是这样只能在终端打印,不是我们想要的结果
我们还需要在页面中像这样显示结果

4.0版本(在页面中显示)

上次我们学到了访问templates模板中的html文件可以看到完整网页,我们可以往模板里面传数据,这样访问就可以从页面上看到了。
模板实际上就是html只不过还兼容一定模板语法。(但是浏览器不兼容模板)
我们新建html文件

然后我们想要通过python代码向html文件里传输数据
我们只需要在这里挖一个坑,然后往这个坑里传输数据即可。

<head>
    <meta charset="UTF-8">
    <title>studentlist</title>
</head>
<body>
<h2>windows</h2>
<h3>{{ hobby }}</h3>
</body>
</html>

第7行两个大括号中间hobby就是一个坑,暂时还没有数据传入
我们再将views中的getstudentsre return响应改成如下:

def get_students(request):
    students = Student.objects.all()#objects是ORM提供学生操作的一个入口,抽象出来的操作入口
    for student in students:
        print(student.s_name)
    #return HttpResponse('student List')
    return render(request,'student_list.html')

这时候我们直接访问页面会发现是可以打开的,只是看不见大括号,并且没有报错,但是h3标签还是在的。

ctrl+p查看参数提示


第三个参数context是一个文本内容,context是一个字典,我们可以在字典里传递我们想要传递的数据
操作如下:

def get_students(request):
    students = Student.objects.all()#objects是ORM提供学生操作的一个入口,抽象出来的操作入口
    for student in students:
        print(student.s_name)
    #return HttpResponse('student List')
    context = {'hobby':'playgames'
               }
    return render(request,'student_list.html',context=context)

我们在字典添加了hobby的键,这样在html中就会把坑中的hobby用这里字典中hobby对应的值去替换,查看页面

这样我们就能观察到了。
同理你也可以多挖一点坑,然后在字典里再添加对应的键值对即可。
这样我们把students也假如到字典中

def get_students(request):
    students = Student.objects.all()#objects是ORM提供学生操作的一个入口,抽象出来的操作入口
    for student in students:
        print(student.s_name)
    #return HttpResponse('student List')
    context = {'hobby':'playgames',
               'students':students
               }
    return render(request,'student_list.html',context=context)

那么问题来了,我们如何让html中显示学生列表,因为我们不知道学生有多少个,我们可以采用for循环配合html列表ul标签使用
html如下:

我们可以输入for然后按tab建自动补齐循环,选择循环对象。
接着我们补全内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>studentlist</title>
</head>
<body>
<h2>windows</h2>
<h3>{{ hobby }}</h3>
<h1>Student list</h1>
<hr>
<ul>
{% for student in students %}
<li>{{ student.s_name }}</li>
{% endfor %}


</ul>

这样我们打开网页观察:
image.png
像新闻网站只是样式漂亮一点,原理差不多。
补充:

    标签定义无序列表

    标签在 HTML 页面中创建一条水平线。
    水平分隔线(horizontal rule)可以在视觉上将文档分隔成各个部分。
  • 标签定义列表项目。
  • 标签可用在有序列表 (
      ) 和无序列表 (
        ) 中。

        流程回顾

        一、添加数据

        建立stedent模型,然后用save插入进数据库

        二、数据检索

        students=student.objects.all()
        将数据赋给students

        三、渲染数据

        我们通过渲染render里的参数context以字典形式传递给html

        四、使用模板语言显示在页面上

        利用for循环

        模板语法浏览器不能识别,很多web编程语言都有模板语法像java,php等等,模板语言在到达浏览器之前,就已经被程序转换成html语言了。

        利用Django更新学生信息

        先明确一点,我们的数据更新和删除是基于查询的,先查出来再删除更新。

        two中添加路由

        url(`'updatestudent/',views.update_student)`

        two中添加views函数

        def update_student(request):
            student = Student.objects.get(pk=2)#pk是主键的意思,objects.get是模型类中的一个获取数据的方法括号里加条件
            student.s_name = '王二麻子'#将刚刚的名字改为新名字
            student.save()#更新到数据库中
            return HttpResponse('student update success')

        运行访问查看结果


        可以看到id为2的姓名已经变成了王二麻子,不管是网页还是数据库都已经更改了

        利用Django删除一个学生信息

        two中添加路由


        url(`'deletestudent/',views.delete_student)`

        two中添加views函数

        def delete_student(request):
            student =Student.objects.get(pk=3)
            student.delete()
            return HttpResponse('student delete success')

        运行访问查看结果:

        成功删除id=3的同学

        总结

        我们使用了ORM对数据操作的增删改查
        存储

        • 存储:save()

        查询

        • 查询所有:objects.all()
        • 查询单个:objects.get(pk=xx)

        更新

        • 基于查询的
        • 插好的对象,修改属性,然后save()
        • 如何识别哪个操作是更新,哪个操作是存储?答:基于主键值,主键值存在是更新,不存在是创建存储

        删除

        • 基于查询
        • 调用delete()
最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏