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

发布时间:2023年12月17日

第一章 Django 基本使用
第二章 Django URL路由系统
第三章 Django 视图系统
第四章 Django 模板系统
第五章 Django 数据模型系统(基本使用)
第六章 Django 数据模型系统(多表操作)
第七章 Django 用户认证与会话技术
第八章 Django CSRF防护



了解静态网址与动态网址

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

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

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

image-20231115205504354

ORM是什么

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

ORM优势:不必熟悉复杂的SQL语句,容易上手,避免新手写SQL效率问题Python代码存储流程

Model模型类定义

linux新建项目

# 终端执行命令
django-admin startproject  orm

linux 创建应用

# 终端执行命令
cd orm
python3 manage.py startapp myorm

修改django允许访问的

# 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表,并包含字段

# 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名称

# 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的数据库迁移工具)来自动执行迁移。

# 终端上执行命令
python3 manage.py makemigrations
python3 manage.py migrate

表名默认名称

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

使用MySQL数据库

启动mysql两种方式

docker启动一个mysql

# 终端执行命令
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

# 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
# 终端执行命令,进行启动数据库
docker-compose up -d

数据库创建库

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

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

image-20231115220841767

Django安装pymysql模块

# 终端执行命令
pip install pymysql

Django指定数据库驱动

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

# 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。
# 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迁移文件生成表

# 终端执行命令
python3 manage.py migrate

image-20231115221203262

登录数据库验证是否成功

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

use orm_test;
show tables;

image-20231115222105042

这个是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项目

# 终端上执行命令
python3 manage.py runserver 0.0.0.0:8080

image-20231115222450274

验证

http://49.232.221.200:8080/

image-20231115222504457

ORM增删改查

启动mysql日志(测试环境)

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

show variables like '%general%';
set global general_log=on;

image-20231120214504866

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

命令行增加(1)

命令行进行增加

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

image-20231119211355627

# 再项目目录下进行执行
python3 manage.py shell
from myorm.models import User
from myorm.models import User

image-20231119211521139

image-20231119211416181

Django项目增加(2)

使用Django项目进行增加

路由
# 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'))
]
路由
# myorm/urls.py
from django.urls import include, path
from myorm import views
urlpatterns = [
    path('index',views.index)
]
视图
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

image-20231119212330416

image-20231119212403609

Django表单提交(3)

路由
# myorm/urls.py
from django.urls import include, path
from myorm import views
urlpatterns = [
    path('index',views.index)
]
视图
# 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)}")
页面
<!-- 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防护功能
# 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',
]
验证

image-20231119215153458

image-20231119215207501

image-20231119215239849

使用save方式(4)

命令行进行执行

# 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()
验证

image-20231119220410451

image-20231119220417968

image-20231120212556000

获取数据库表所有数据

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

路由
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("listuser/$",views.list_user)
]
视图
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/

image-20231120212208905

根据条件获取数据

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

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

路由
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("listcondition/$",views.list_condition)
]
视图
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/

image-20231120212748306

根据一条数据

User.objects.get(id=2)

路由
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("listcondition/$",views.list_condition)
]
视图
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/

image-20231120213121421

image-20231120213354316

路由
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("modify/$",views.modify)
]
视图
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/

image-20231120213505836

image-20231120213516268

image-20231120213745818

路由
# myrom/urls.py
from django.urls import include, path, re_path
from myorm import views
urlpatterns = [
    re_path("userdel/$",views.userdel)
]
视图
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/

image-20231120213840126

image-20231120213853379

Django内置管理后台

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

django默认的管理员网址

路由

# 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

image-20231127205537976

创建管理员账户

python manage.py createsuperuser

设置的账户是admin 密码是 admin

image-20231127210318593

登录

注册模型

# myorm/admin.py
from django.contrib import admin
from myorm import models

# Register your models here.

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

image-20231127210756557

image-20231127210906515

后台显示为中文

# orm/setting.py
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = False

image-20231127211704681

image-20231127211838339

通过管理后台增加

image-20231127211948981

image-20231127212038639

保存后,出现下方界面

image-20231127212055594

image-20231127212125246

通过管理后台修改

image-20231127212157497

image-20231127212235083

image-20231127212243241

image-20231127212253613

通过管理后台删除

image-20231127212323341

image-20231127212333051

image-20231127212341386

image-20231127212349997

image-20231127212413075

模型中的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

# 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"] # 对象的默认顺序,用于获取对象列表时
python3 manage.py makemigrations
python3 manage.py migrate

image-20231128215117453

http://49.232.221.200:8080/admin/

image-20231128215219769

例子2

# 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

image-20231128215451685

验证

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

QuerySet对象序列号

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

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

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

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

    ? 使用内建函数 serializers

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

路由

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

视图

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/

image-20231128220700650

文章来源:https://blog.csdn.net/weixin_42434700/article/details/134982552
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。