第五章 Django 数据模型系统(基本使用)

第一章 Django 基本使用

第二章 Django URL路由系统

第三章 Django 视图系统

第四章 Django 模板系统

第五章 Django 数据模型系统(基本使用)

第六章 Django 数据模型系统(多表操作)

第七章 Django 用户认证与会话技术

第八章 Django CSRF防护


文章目录


了解静态网址与动态网址

静态网站和动态网站是两种不同类型的网站,它们在页面内容、URL结构、数据库支持、交互性、技术实现、更新和维护以及适用场景等方面存在明显的区别。

静态网站,也被称为静态网页,其页面内容相对固定,不随用户或时间的变化而变化。它不需要后台数据库的支持,当用户请求页面时,服务器直接返回预先编辑好的页面内容。静态网站的URL结构通常比较简单,一般以.html、.shtml等结尾。然而,静态网页的内容一旦确定,就很难进行修改和更新。

动态网站则利用数据库存储和管理数据,能够根据用户的操作或其他参数变化来显示不同的内容。它的URL结构可能相对复杂,可能包含一些特殊字符或参数。此外,动态网站可以实现更丰富的交互性。动态网页并不是指网页上有动画或者滚动字幕等视觉上的"动态效果",无论网页是否具有动态效果,只要是采用动态网站技术生成的网页都称为动态网页。

ORM是什么

对象关系映射:是一种程序设计技术,用于实现面向对象编程语言 里不同类型系统的数据之间的转换。简单来说就是在编程语言中实现的一种虚拟对象数据库。我们对虚拟对象 数据库进行操作,它会转换成具体的SQL去操作数据库,这样一来我们就不需要学习复杂的SQL语句了。

ORM优势 :不必熟悉复杂的SQL语句,容易上手,避免新手写SQL效率问题

Model模型类定义

linux新建项目

bash 复制代码
# 终端执行命令
django-admin startproject  orm

linux 创建应用

bash 复制代码
# 终端执行命令
cd orm
python3 manage.py startapp myorm

修改django允许访问的

python 复制代码
# orm/setting.py
ALLOWED_HOSTS = ['*']

模型类常用字段

字段类型 描述
AutoField(**options) ID自动递增,会自动添加到模型中
BooleanField(**options) 布尔值字段(true/false),默认值是None
CharField(max_length=None[,**options]) 存储各种长度的字符串
EmailField([max_length=254,**options]) 邮件地址,会检查是否合法
FileField([upload_to=None,max_length=100,**options]) 保存上传文件。upload_to是保存本地的目录路径
FloatField([**options]) 浮点数
IntegerField([**options]) 整数
GenericIPAddressField(protocol='both', unpack_ipv4=False, **options) IP地址
TextField([**options]) 大文本字符串
URLField([max_length=200,**options]) 字符串类型的URL
DateTimeField([auto_now=False,auto_now_add=False,**options]) 日期和时间 • auto_now=True时,第二次保存对象时自动设置为当前时间。 最后一次修改的时间戳,比如更新。 • auto_now_add=True时,第一次创建时自动设置当前时间。用 建时间的时间戳,比如新增。
DateField([auto_now=False,auto_now_add=False,**options]) 日期
TimeField([auto_now=False,auto_now_add=False,**options]) 时间

Django中定义表

使用模型类定义一个User表,并包含字段

python 复制代码
# myorm/models.py
from django.db import models

# Create your models here.
# 定义一个用户表,继承model类
class User(models.Model):
    user = models.CharField(max_length=30) # 定义user字段,并定义为字符串以及设置长度
    name = models.CharField(max_length=30) # 定义name字段,并定义为字符串以及设置长度
    sex = models.CharField(max_length=10) # 定义sex字段,并定义为字符串以及设置长度
    age = models.IntegerField() # 定义age字段,并定义为整型
    label = models.CharField(max_length=100) # 定义label字段,并定义为字符串以及设置长度

Django中配置表

再setting.py配置文件中INSTALLED_APPS列表添加APP名称

python 复制代码
# orm/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myorm', # 增加这一行
]

Django生成具体的数据库表

1.python manage.py makemigrations:这个命令用于根据你对模型的更改生成迁移文件。这些迁移文件包含了将你的模型更改应用到数据库所需的SQL语句。当你对模型进行更改时,例如添加、删除或修改字段,你需要运行这个命令来生成相应的迁移文件。

2.python manage.py migrate:这个命令用于执行数据库迁移。它会根据你在上一步生成的迁移文件,将更改应用到数据库中。这通常在开发环境中使用,以确保你的模型更改不会破坏现有的数据。在生产环境中,你可能需要手动执行迁移,或者使用其他工具(如Django的数据库迁移工具)来自动执行迁移。

bash 复制代码
# 终端上执行命令
python3 manage.py makemigrations
python3 manage.py migrate

表名默认名称

生成表名的默认格式:应用名_模型类名小写

使用MySQL数据库

启动mysql两种方式

docker启动一个mysql

bash 复制代码
# 终端执行命令
docker run -d \
--name db \
-p 3306:3306 \
-v mysqldata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123.com \
MYSQL:5.7.21 --character-set-server=utf8

docker-compsoe启动一个mysql

yaml 复制代码
# docker-compose.yaml
version: "2"
services:
  mysqld:
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: "123.com"
    image: mysql:5.7.21
    restart: always
    volumes:
      - "./db:/var/lib/mysql"
    ports:
      - "3306:3306"
    command:
      #mysql5.7及以上 版本 默认连接方式 不是以密码形式连接 所以远程连接不方便 改为密码连接
      --default-authentication-plugin=mysql_native_password 
      --character-set-server=utf8mb4
      --explicit_defaults_for_timestamp=true
      --max_allowed_packet=64M
      --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
      --skip-name-resolve
bash 复制代码
# 终端执行命令,进行启动数据库
docker-compose up -d

数据库创建库

bash 复制代码
# 终端上执行命令
docker exec -it 数据库ID bash # 进入数据库容器
mysql -u root -p'123.com'

## 登录数据库后创建库
create database orm_test;
## 验证是否创建成功
show databases;

Django安装pymysql模块

bash 复制代码
# 终端执行命令
pip install pymysql

Django指定数据库驱动

pymysql库安装为MySQLdb模块,目的是为了让Python在处理MySQL数据库时,能够识别并使用pymysql库提供的API

python 复制代码
# myorm/__init__.py
import pymysql
pymysql.install_as_MySQLdb()

修改DJango指定mysql数据源

  • 'ENGINE': 'django.db.backends.mysql': 指定使用的数据库引擎为MySQL。
  • 'NAME': 'orm_test': 数据库的名称,这里使用的是名为"orm_test"的数据库。
  • 'USER': 'root': 数据库的用户名,这里使用的是"root"用户。
  • 'PASSWORD': '123.com': 数据库的密码,这里使用的是"123.com"作为密码。
  • 'HOST': '10.0.24.2': 数据库服务器的主机地址,这里使用的是IP地址"10.0.24.2"。
  • 'PORT': '3306': 数据库服务器的端口号,这里使用的是默认的MySQL端口号3306。
python 复制代码
# orm/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'orm_test',
        'USER': 'root',
        'PASSWORD': '123.com',
        'HOST': '10.0.24.2',
        'PORT': '3306',
    }
}

Django迁移文件生成表

bash 复制代码
# 终端执行命令
python3 manage.py migrate

登录数据库验证是否成功

bash 复制代码
# 终端上执行命令
docker exec -it 数据库ID bash # 进入数据库容器
mysql -u root -p'123.com'

use orm_test;
show tables;

这个是Django框架默认的数据表

  • 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: 存储用户的会话信息,包括会话ID、过期时间等。

启动Django项目

bash 复制代码
# 终端上执行命令
python3 manage.py runserver 0.0.0.0:8080

验证

http://49.232.221.200:8080/

ORM增删改查

启动mysql日志(测试环境)

general_log是MySQL的通用查询日志,它记录了所有客户端执行的语句。这个日志可以帮助开发者和数据库管理员了解数据库的使用情况,诊断问题和优化性能。但是,由于它会记录所有的查询语句,所以可能会影响数据库的性能。在生产环境中,建议关闭此日志功能。

bash 复制代码
show variables like '%general%';
set global general_log=on;

下面所有增删改查的日志都会记录到这,学习时候可以参考

命令行增加(1)

命令行进行增加

python3 manage.py shell 是一个命令,用于启动 Django 项目的交互式 shell。在 shell 中,你可以执行各种数据库操作、模型查询等操作。

python 复制代码
# 再项目目录下进行执行
python3 manage.py shell
from myorm.models import User
from myorm.models import User

Django项目增加(2)

使用Django项目进行增加

路由
python 复制代码
# orm/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myorm/',include('myorm.urls'))
]
路由
python 复制代码
# myorm/urls.py
from django.urls import include, path
from myorm import views
urlpatterns = [
    path('index',views.index)
]
视图
python 复制代码
from django.shortcuts import render, HttpResponse
from myorm.models import User

# Create your views here.

def index(request):
    try:
        User.objects.create(user="wang2", name="王2", sex="男2", age=40, label="打工人2")
        return HttpResponse("添加成功")
    except Exception as e:
        return HttpResponse(f"失败原因:{str(e)}")
验证

http://49.232.221.200:8080/myorm/index

Django表单提交(3)

路由
python 复制代码
# myorm/urls.py
from django.urls import include, path
from myorm import views
urlpatterns = [
    path('index',views.index)
]
视图
python 复制代码
# from django.shortcuts import render, HttpResponse
from myorm.models import User

# Create your views here.

def add_user(request):
    if request.method == "GET":
        return render(request,"register.html")
    elif request.method == "POST":
        username = request.POST.get('user')
        name = request.POST.get('name')
        sex = request.POST.get('sex')
        age = request.POST.get('age')
        label = request.POST.get('label')
        try:
            User.objects.create(user=username, name=name, sex=sex, age=age, label=label)
            return HttpResponse("添加成功")
        except Exception as e:
            return HttpResponse(f"失败原因:{str(e)}")
页面
html 复制代码
<!-- myrom/templates/register.html -->
</html>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户注册</title>
    </head>
    <body>
        <form action="" method="post">
            <h1>用户注册</h1>
            用户名:<input type="text" name="user" required><br>
            姓名:<input type="text" name="name" required><br>
            性别:<select name="sex" required>
                <option value="男">男</option>
                <option value="女">女</option>
            </select><br>
            年龄:<input type="number" name="age" min="0" required><br>
            标签:<input type="text" name="label"><br>
            <button type="submit">提交</button>
        </form>        
    </body>

</html>
关闭CSRF防护功能
python 复制代码
# orm/setting.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware', # 注释这行
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
验证

使用save方式(4)

命令行进行执行

bash 复制代码
# orm项目下
from myorm.models import User
user = User()
user.user = "wang3"
user.name = "王3"
user.sex = "男3"
user.age = 50
user.label = "IT3"
user.save()
验证

获取数据库表所有数据

User.objects.all() # 获取全部数据

路由
python 复制代码
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("listuser/$",views.list_user)
]
视图
python 复制代码
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from myorm.models import User


# Create your views here.

def list_user(request):
    users = User.objects.all()
    result = [{'name': user.name, 'sex': user.sex ,'age':user.age} for user in users]
    return JsonResponse(result, safe=False)
验证

http://49.232.221.200:8080/myorm/listuser/

根据条件获取数据

User.objects.filter(user='wang') # 获取用户为wang的

User.objects.filter(age__gt=28) # 获取年龄大于28的

路由
python 复制代码
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("listcondition/$",views.list_condition)
]
视图
python 复制代码
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from myorm.models import User


# Create your views here.

def list_condition(request):
    # users = User.objects.filter(user='wang')
    users = User.objects.filter(age__gt=30)
    result = [{'name': user.name, 'sex': user.sex ,'age':user.age} for user in users]
    return JsonResponse(result, safe=False)
验证

http://49.232.221.200:8080/myorm/listcondition/

根据一条数据

User.objects.get(id=2)

路由
python 复制代码
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("listcondition/$",views.list_condition)
]
视图
python 复制代码
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from myorm.models import User


# Create your views here.

def list_condition(request):
    user = User.objects.get(id=2)
    result = [{'name': user.name, 'sex': user.sex, 'age': user.age}]
    return JsonResponse(result, safe=False)
验证

http://49.232.221.200:8080/myorm/listcondition/

路由
python 复制代码
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("modify/$",views.modify)
]
视图
python 复制代码
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from myorm.models import User


# Create your views here.

def modify(request):
    try:
        User.objects.filter(user='wang').update(age=27,label='公关')
        return HttpResponse("修改成功")
    except Exception as e:
        return HttpResponse(f"失败原因:{str(e)}")
验证

http://49.232.221.200:8080/myorm/modify/

路由
python 复制代码
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("userdel/$",views.userdel)
]
视图
python 复制代码
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from myorm.models import User


# Create your views here.

def userdel(request):
    try:
        User.objects.filter(user='wang3').delete()
        return HttpResponse("删除成功")
    except Exception as e:
        return HttpResponse(f"失败原因:{str(e)}")
验证

http://49.232.221.200:8080/myorm/userdel/

Django内置管理后台

网站开发,一般都会有一个管理后台系统,向管理员提供操作

django默认的管理员网址

路由

python 复制代码
# orm/urls.py
from django.contrib import admin  # 内建管理后台功能
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls)  # 内建管理后台访问地址
]

验证

http://49.232.221.200:8080/admin

创建管理员账户

bash 复制代码
python manage.py createsuperuser

设置的账户是admin 密码是 admin

注册模型

python 复制代码
# myorm/admin.py
from django.contrib import admin
from myorm import models

# Register your models here.

admin.site.register(models.User) # 把User表注册到django的管理后台中

后台显示为中文

python 复制代码
# orm/setting.py
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = False

通过管理后台增加

保存后,出现下方界面

通过管理后台修改

通过管理后台删除

模型中的Meata类与方法

Django模型类的Meta是一个内部类,用于定义模型的一些元数据。这些元数据包括数据库表名、排序方式、是否允许空值等。在模型类中,可以通过继承Model类并添加Meta子类来定义Meta属性

元选项 描述
db_table 指定数据库表名。默认情况下,Django会使用模型类的英文名称转换为小写字母加上"_set"后缀作为表名
ordering 指定模型实例在查询结果中的排序方式。可以使用字符串列表或字段对象列表来指定排序字段
db_table 指定生成的数据库表名称,默认是"应用名_模型名"
verbose_name 定义一个易读的模型名称,默认会加一个复数s
verbose_name_plural 定义一个易读的模型名称,不带复数s

模型类常用字段

选项 描述
null 如果为True,字段用NULL当做空值,默认False
blank 如果为True,允许为空,默认False
db_index 如果为True,为此字段建立索引
default 字段的默认值
primary_key 如果为True,设置为主键
unique 如果为True,保持这个字段的值唯一
verbose_name 易读的名称,管理后台会以这个名称显示

例子1

python 复制代码
# myorm/models.py
from django.db import models

# Create your models here.
# 定义一个用户表,继承model类
class User(models.Model):
    user = models.CharField(max_length=30) # 定义user字段,并定义为字符串以及设置长度
    name = models.CharField(max_length=30) # 定义name字段,并定义为字符串以及设置长度
    sex = models.CharField(max_length=10) # 定义sex字段,并定义为字符串以及设置长度
    age = models.IntegerField() # 定义age字段,并定义为整型
    label = models.CharField(max_length=100) # 定义label字段,并定义为字符串以及设置长度
    
    class Meta:
        app_label = "myorm" # 指定APP名称
        db_table = 'user'   # 自定义生成的表名
        managed = True     # Django自动管理数据库表
        verbose_name = '用户表'  # 对象的可读名称
        verbose_name_plural = '用户表'  # 名称复数形式
        ordering = ["sex"] # 对象的默认顺序,用于获取对象列表时
bash 复制代码
python3 manage.py makemigrations
python3 manage.py migrate

http://49.232.221.200:8080/admin/

例子2

python 复制代码
# myorm/models.py
from django.db import models

# Create your models here.
# 定义一个用户表,继承model类
class User(models.Model):
    user = models.CharField(max_length=30) # 定义user字段,并定义为字符串以及设置长度
    name = models.CharField(max_length=30) # 定义name字段,并定义为字符串以及设置长度
    sex = models.CharField(max_length=10) # 定义sex字段,并定义为字符串以及设置长度
    age = models.IntegerField() # 定义age字段,并定义为整型
    label = models.CharField(max_length=100) # 定义label字段,并定义为字符串以及设置长度
    
    class Meta:
        app_label = "myorm" # 指定APP名称
        db_table = 'user'   # 自定义生成的表名
        managed = True     # Django自动管理数据库表
        verbose_name = '用户表'  # 对象的可读名称
        verbose_name_plural = '用户表'  # 名称复数形式
        ordering = ["sex"] # 对象的默认顺序,用于获取对象列表时
    def __str__(self) -> str:
        return self.name

验证

http://49.232.221.200:8080/myorm/query/

QuerySet对象序列号

  • 序列化:将Python对象转为传输的数据格式

  • 反序列化:将传输的数据格式转为Python对象

    ORM查询返回的是QuerySet对象,如果你要提供数据接口,这显然是不行的。

    有两种方法可以转为JSON字符串:

    • 使用内建函数 serializers

    • 遍历QuerySet对象将字段拼接成字典,再通过json库编码

路由

python 复制代码
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("query/$",views.get_queryset)
]

视图

python 复制代码
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from myorm.models import User
from django.core import serializers

# Create your views here.

def get_queryset(request):
    data = User.objects.all()
    data1 = serializers.serialize('json',data)
    return HttpResponse(data1)

验证

http://49.232.221.200:8080/myorm/query/

相关推荐
带刺的坐椅4 分钟前
FastMCP(python)和 SolonMCP(java)的体验比较(不能说一样,但真的很像)
java·python·solon·mcp·fastmcp
今天阳光明媚吗29 分钟前
SQlite数据库
数据库·sqlite
极小狐1 小时前
如何从极狐GitLab 容器镜像库中删除容器镜像?
java·linux·开发语言·数据库·python·elasticsearch·gitlab
gjc5921 小时前
MySQL OCP试题解析(3)
数据库·mysql·开闭原则
cliff,2 小时前
数据提取之BeautifulSoup4快速使用
笔记·python·学习
坐吃山猪2 小时前
Python多环境管理指南
开发语言·python
伊织code2 小时前
PyTorch API 4 - 分布式通信、分布式张量
pytorch·python·ai·api·-·4·分布式通信、分布式张量
houzhizhen2 小时前
SQL JOIN 关联条件和 where 条件的异同
前端·数据库·sql
小声读源码2 小时前
【部署】win10的wsl环境下调试dify的api后端服务
vscode·python·docker·uv·dify·remote-ssh·pyenv
yy鹈鹕灌顶2 小时前
Redis 基础详解:从入门到精通
数据库·redis·缓存