django的基本使用-ORM(二)

一、简介

ORM对象关系映射,它允许你使用类和对象对数据库进行操作,从而避免通过SQL语句操作数据库

模型层: 负责和数据库之间进行通信

模型是一个Python类,它是由django.db.models.Model派生出的子类

一个模型类代表数据库中的一张表

模型类中每一个类属性都代表数据库中的一个字段

模型是数据交互的接口,是表示和操作数据库的方法和方式

二、基本配置

1.配置settings.py

shell 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydatabase',
        'USER': 'admin',
        'PASSWORD': 'abc123,',
        'HOST': '192.168.1.23',
        'PORT': '3306',
    }
}

LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
常用配置
1.BASE_DIR:项目的绝对路径
2.DEBUG: 启动模式
	True: 调试模式
		检测代码改动后,立刻重启服务
	Fasle: 正式启动模式 / 上线模式3.ALLOWED_HOSTS: 允许访问本机的客户端主机,'*' 表示允许所有主机
4.DATABASES: 连接的数据库
5.LANGUAGE_CODE: 显示语言
	zh-Hans 表示用中文显示

2.安装mysqlclient

因为我们使用mysql作为后端,所以要安装mysqlclient库

shell 复制代码
pip install mysqlclient

3.创建应用

创建app1应用。发现在应用目录下多了app1目录

python manage.py startapp app1

4.注册应用

在setting.py中注册app1应用

python 复制代码
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app1'  #在这里加入我们刚才创建的app1应用
]

5.创建对应的数据库表

c 复制代码
create database mydatabase default character set utf8mb4;
grant all on mydatabase.* to 'admin'@'%' identified by 'abc123,';
grant all on mydatabase.* to 'admin'@'localhost' identified by 'abc123,';
grant all on mydatabase.* to 'admin'@'127.0.0.1' identified by 'abc123,'
flush privileges;


修改该数据库字符集
alter database mydatabase character set utf8mb4 collate utf8mb4_unicode_ci;

迁移数据库,也就是使用python语法创建默认的库

python 复制代码
python manage.py migrate

在库中查看,已经生成默认的数据库

mysql 复制代码
mysql> use mydatabase
mysql> show tables;
+----------------------------+
| Tables_in_mydatabase       |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.00 sec)

6.启动django测试

shell 复制代码
python manage.py runserver

三、ORM(模型)

1.创建模型类流程

在"应用(app1)"下的models.py中编写模型类

c 复制代码
[root@node5 music]# vim models.py 
#文件中自动导入了models包,因为这是一个包,其实就是执行了__init__.py文件。在此文件中又导入了base.py中的Model类
from django.db import models

2.语法:

模型类名也就是表名

c 复制代码
class 模型类名(models.Model):
	字段名1 = models.字段类型(字段选项)
	字段名2 = models.字段类型(字段选项)

3.实例

3.1 创建model类

编辑app1应用下的models.py文件

shell 复制代码
class student(models.Model):
    class Meta:
        db_table = 'my_table1'

    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=20)
    age = models.IntegerField()
shell 复制代码
解释:
class student是模型类 继承models.Model类
Meta: 是自定义生成的表名,如果不定义,表名就是"应用名" + "模型类"组合而成的表名
id,name,age 分别是表中的字段
3.3 开始创建表

这个过程就是将类转换成sql的过程。django中这个过程叫做迁移

python 复制代码
python manage.py makemigrations
python manage.py migrate

3.4 验证

mysql 复制代码
mysql> use mydatabase
mysql> desc my_table1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | NULL    |       |
| name  | varchar(20) | NO   |     | NULL    |       |
| age   | int(11)     | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

四、插入数据

1.方法1:

在app1应用的models.py文件中,直接写入以下语句进行插入数据

c 复制代码
student.objects.create(id=1,name='zhangsan',age=20)

然后命令行执行
python manage.py migrate

查看数据,已经插入成功

mysql 复制代码
mysql> select * from my_table1;
+----+----------+-----+
| id | name     | age |
+----+----------+-----+
|  1 | zhangsan |  20 |
+----+----------+-----+

2.方法2

在视图函数中插入数据。

2.1 设置总路由

编辑项目目录下的urls.py文件

python 复制代码
from django.contrib import admin
from django.urls import path,include


urlpatterns = [
    path('admin/', admin.site.urls),
    path('app1/',include('app1.urls')),
]
2.2 设置分路由

在app1应用下新建urls.py文件。内容如下

python 复制代码
from django.urls import path
from .views import *

urlpatterns = [
    path('', fun_app1),
]
2.3 设置视图函数文件
python 复制代码
# 导入model类中的student类
from .models import student
from django.http import  HttpResponse

def fun_app1(request):
	# 实例化student类
    s1 = student(id=3,name="lisi",age=22)
    # 写入数据,保存到数据库中
    s1.save()
    return  HttpResponse("写入数据库成功!")

五、单表查询数据

1.创建数据库表

我们在数据库中直接创建一个表,用于测试。这里不通过django自带迁移的功能的创建了。

mysql 复制代码
mysql> use mydatabase
mysql> create table my_students1(id int primary key auto_increment,name char(32),age int);
mysql> insert into my_students1 (name,age) values('zhangsan',20),('lisi',20),('wangwu',21),('xiaohong',22),('xiaoming',23);
mysql> select * from my_students1;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   20 |
|  2 | lisi     |   20 |
|  3 | wangwu   |   21 |
|  4 | xiaohong |   22 |
|  5 | xiaoming |   23 |
+----+----------+------+
5 rows in set (0.00 sec)

2.创建模型类

在应用下(app1)的models.py中创建模型类,与刚才在数据库中创建的表建立对应关系.

python 复制代码
class students1(models.Model):
    class Meta:
        db_table = 'my_students1' #这里的表名称一定要和数据库中表名保持一致

    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()

3.查询集合all()

编辑app1下的视图函数文件

c 复制代码
from .models import *
from django.http import  HttpResponse

def fun_app1(request):
	# students1.objects.all返回的是一个django封装的queryset集合。简单理解为一个集合就可以了。
	# 集合中就是每行的记录,也是"模型类的实例对象"。这样遍历就是遍历每个实例对象。这样就可以打印每条数据了
    list = students1.objects.all()
    for i in list:
        print(i.id,i.name,i.age)
    return  HttpResponse("查询成功")

访问视图url路径,日志输出查询数据如下:

python 复制代码
[11/Feb/2024 16:12:57] "GET /app1/ HTTP/1.1" 200 12
1 zhangsan 20 
2 lisi 20 
3 wangwu 21
4 xiaohong 22
5 xiaoming 23

4.集合过滤filter()

filter的返回结果也是一个queryset集合

python 复制代码
from .models import *
from django.http import  HttpResponse

def fun_app1(request):
    list = students1.objects.filter(age=20)
    for i in list:
        print(i.id,i.name,i.age)
    return  HttpResponse("查询成功")

访问视图url路径,日志输出查询数据如下:

python 复制代码
1 zhangsan 20 
2 lisi 20 
[11/Feb/2024 16:18:05] "GET /app1/ HTTP/1.1" 200 12
4.1 大于查询__gt
shell 复制代码
list = students1.objects.filter(age__gt=20)
for i in list:
    print(i.id,i.name,i.age)
4.2 小于查询__lt
shell 复制代码
list = students1.objects.filter(age__lt=23)
for i in list:
    print(i.id,i.name,i.age)
4.3 模糊查询__contains

查询语法:字段名__contains="查询内容"

shell 复制代码
list = students1.objects.filter(name__contains="xiao")
for i in list:
    print(i.id,i.name,i.age)

5.get()

get函数的结果必须是一个结果,要是两个结果都不可以用这个。get的返回结果是一个模型类实例对象。不是queryset集合

python 复制代码
list = students1.objects.get(id=1)
print(list.id,list.name,list.age)

6.取反exclude()

python 复制代码
list = students1.objects.exclude(age=20)
for i in list:
    print(i.id,i.name,i.age)

结果如下:

shell 复制代码
3 wangwu 21
4 xiaohong 22
5 xiaoming 23

7.Q查询

q查询就是或关系查询

python 复制代码
from .models import *
from django.db.models import Q
from django.http import  HttpResponse

def fun_app1(request):
    list = students1.objects.filter(Q(name="xiao") | Q(age=20))
    for i in list:
        print(i.id,i.name,i.age)
    return  HttpResponse("查询成功")

模型类函数有很多,具体可以参照官网

六、修改和删除

修改之前查看表内容

mysql 复制代码
mysql> select * from my_students1;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   20 |
|  2 | lisi     |   20 |
|  3 | wangwu   |   21 |
|  4 | xiaohong |   22 |
|  5 | xiaoming |   23 |
+----+----------+------+
5 rows in set (0.01 sec)

1.修改update()

修改views.py视图函数内容

c 复制代码
from .models import *
from django.db.models import Q
from django.http import  HttpResponse

def fun_app1(request):
    # 先查询年龄等于20的结果集
    list = students1.objects.filter(age=20)
    # 然后直接修改结果集
    list.update(age=30)

    #在查询修改后的结果
    list = students1.objects.filter(age=30)
    for i in list:
        print(i.id,i.name,i.age)
    return  HttpResponse("修改数据成功")

再次查看数据库内容,数据已经成功修改

mysql 复制代码
 mysql> select * from my_students1;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |   30 |
|  2 | lisi     |   30 |
|  3 | wangwu   |   21 |
|  4 | xiaohong |   22 |
|  5 | xiaoming |   23 |
+----+----------+------+
5 rows in set (0.00 sec)

2.删除delete()

shell 复制代码
例子1:
list = students1.objects.filter(age=30)
list.delete()


例子2:
list = students1.objects.get(name='wangwu')
list.delete()

七、多表操作

1.一对多操作

1.1 创建my_publish表。

mysql 复制代码
mysql> use mydatabase
mysql> create table my_publish(id int(10) primary key auto_increment,name varchar(20),addr varchar(50),email varchar(20));
mysql> desc my_publish;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(10)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | YES  |     | NULL    |                |
| addr  | varchar(50) | YES  |     | NULL    |                |
| email | varchar(20) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

1.2.在my_publish表中插入数据

mysql 复制代码
insert into my_publish values(0,'苹果出版社','北京',123),(0,'西瓜出版社','南京',456);
mysql> select * from my_publish;
+------+-----------------+--------+-------+
| id   | name            | addr   | email |
+------+-----------------+--------+-------+
|    1 | 苹果出版社        | 北京   | 123    |
|    2 | 西瓜出版社        | 南京   | 456    |
+------+-----------------+--------+-------+
2 rows in set (0.00 sec)

1.3.创建my_book表

mysql 复制代码
create table my_book(id int(10) primary key auto_increment,title varchar(20),price double(5,2),publishDate datetime,publish_id int(10),foreign key(publish_id)
references my_publish(id));

查看创建的表结构

mysql 复制代码
mysql> desc my_book;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(10)     | NO   | PRI | NULL    | auto_increment |
| title       | varchar(20) | YES  |     | NULL    |                |
| price       | double(5,2) | YES  |     | NULL    |                |
| publishDate | datetime    | YES  |     | NULL    |                |
| publish_id  | int(10)     | YES  | MUL | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

1.4 手动插入数据进行测试

mysql 复制代码
mysql> insert into my_book values(0,"西游记",199.00,now(),1);
Query OK, 1 row affected (0.00 sec)

# 查看数据是否插入成功
mysql> select * from my_book;
+------+-----------+--------+---------------------+------------+
| id   | title     | price  | publishDate         | publish_id |
+------+-----------+--------+---------------------+------------+
|    1 | 西游记    | 199.00 | 2024-02-11 21:08:50 |          1 |
+------+-----------+--------+---------------------+------------+
1 row in set (0.00 sec)

1.5 建立模型类

编辑app1应用下的models.py文件

c 复制代码
from django.db import models

# 创建my_publish表的模型类
class my_publish(models.Model):
    class Meta:
        db_table = 'my_publish' #这里的表名称一定要和数据库中表名保持一致

    id = models.AutoField(max_length=10,primary_key=True)
    name = models.CharField(max_length=20)
    addr = models.CharField(max_length=50)
    email = models.CharField(max_length=50)


# 创建my_book表的模型类
class my_book(models.Model):
    class Meta:
        db_table = 'my_book'  # 这里的表名称一定要和数据库中表名保持一致

    id = models.AutoField(max_length=10,primary_key=True)
    title = models.CharField(max_length=20)
    price = models.FloatField()
    # auto_now_add 新增数据库数据库的时候才会触发这个时间,修改数据不会触发,修改要触发时间需要使用auto_now=True
    publishDate = models.DateTimeField(auto_now_add=True)
    
    #注意: publish 是外键,外键的名称django会自动补充上"_id".正好和数据库中的字段pubish_id字段对应上
    publish = models.ForeignKey(my_publish,null=True,on_delete=models.SET_NULL)

1.6 使用视图查询my_book数据

这里没有直接对my_book表直接进行插入数据操作而是先查询,原因是先看上边的的模型类定义的是否正确

python 复制代码
from .models import *
from django.db.models import Q
from django.http import  HttpResponse

def fun_app1(request):
    list = my_book.objects.all()
    for i in  list:
        print(i.id,i.title,i.price,i.publishDate,i.publish_id)

    return  HttpResponse("查询数据成功")

1.7 使用视图插入数据

在app1应用下的视图函数

c 复制代码
from .models import *
from django.http import  HttpResponse

def fun_app1(request):
    # 这里要注意,获取id时需要使用get,不能使用fiter,因为get返回的是结果,filter返回是查询对象集合
    # 这里pk是自动指向my_publish的主键。pk是primary key的简写。在django中pk是固定写法
    publish_id = my_publish.objects.get(pk=2)

    my_book.objects.create(title="水浒传",price="88.00",publish=publish_id)
    return  HttpResponse("插入数据成功")

查看数据库数据如下:

mysql 复制代码
mysql> select * from my_book;
+----+-----------+--------+---------------------+------------+
| id | title     | price  | publishDate         | publish_id |
+----+-----------+--------+---------------------+------------+
|  1 | 西游记    | 199.00 | 2024-02-11 23:08:45 |          1  |
|  2 | 水浒传    |  88.00 | 2024-02-12 04:25:09 |          2  |
+----+-----------+--------+---------------------+------------+
2 rows in set (0.00 sec)-+

另外一种写法前边也介绍过了

c 复制代码
from .models import *
from django.http import  HttpResponse

def fun_app1(request):
    publish_id = my_publish.objects.get(pk=2)

    book1 = my_book(title="三国演义",price="188.00",publish=publish_id)
    book1.save()
    return  HttpResponse("插入数据成功")

结果如下:

mysql 复制代码
mysql> select * from my_book;
+----+--------------+--------+---------------------+------------+
| id | title        | price  | publishDate         | publish_id |
+----+--------------+--------+---------------------+------------+
|  1 | 西游记       | 199.00 | 2024-02-11 23:08:45 |          1  |
|  2 | 水浒传       |  88.00 | 2024-02-12 04:25:09 |          2  |
|  3 | 三国演义     | 188.00 | 2024-02-12 04:30:24 |          2  |
+----+--------------+--------+---------------------+------------+
相关推荐
sdaxue.com22 分钟前
帝国CMS:如何去掉帝国CMS登录界面的认证码登录
数据库·github·网站·帝国cms·认证码
o(╥﹏╥)1 小时前
linux(ubuntu )卡死怎么强制重启
linux·数据库·ubuntu·系统安全
阿里嘎多学长1 小时前
docker怎么部署高斯数据库
运维·数据库·docker·容器
Yuan_o_1 小时前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
Sunyanhui11 小时前
牛客网 SQL36查找后排序
数据库·sql·mysql
老王笔记2 小时前
MHA binlog server
数据库·mysql
lovelin+v175030409662 小时前
安全性升级:API接口在零信任架构下的安全防护策略
大数据·数据库·人工智能·爬虫·数据分析
isSamle3 小时前
使用Vue+Django开发的旅游路书应用
前端·vue.js·django
DT辰白3 小时前
基于Redis的网关鉴权方案与性能优化
数据库·redis·缓存