Django基础-Model数据库操作

表数据操作简介

表数据操作主要包含对数据和表的增删改查,表类型有单表,一对多类型表和多对多类型表。

创建表数据

表数据代指
类名生成数据库表名
类中models.字段类型生成数据库字段
models.OneToOneField一对一
models.ForeignKey一对多表
models.ManyToManyField多对多表

OneToOneField()参数

 OneToOneField(ForeignKey)
        to,                         # 要进行关联的表名
        to_field=None               # 要关联的表中的字段名称
        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为

                                    ###### 对于一对一 ######
                                    # 1. 一对一其实就是 一对多 + 唯一索引
                                    # 2.当两个类之间有继承关系时,默认会创建一个一对一字段
                                    # 如下会在A表中额外增加一个c_ptr_id列且唯一:
                                            class C(models.Model):
                                                nid = models.AutoField(primary_key=True)
                                                part = models.CharField(max_length=12)

                                            class A(C):
                                                id = models.AutoField(primary_key=True)
                                                code = models.CharField(max_length=1)

ForeignKey()参数


    ForeignKey(ForeignObject) # ForeignObject(RelatedField)
        to,                         # 要进行关联的表名
        to_field=None,              # 要关联的表中的字段名称
        on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为
                                        - models.CASCADE,删除关联数据,与之关联也删除
                                        - models.DO_NOTHING,删除关联数据,引发错误IntegrityError
                                        - models.PROTECT,删除关联数据,引发错误ProtectedError
                                        - models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
                                        - models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
                                        - models.SET,删除关联数据,
                                                      a. 与之关联的值设置为指定值,设置:models.SET(值)
                                                      b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

                                                        def func():
                                                            return 10

                                                        class MyModel(models.Model):
                                                            user = models.ForeignKey(
                                                                to="User",
                                                                to_field="id"
                                                                on_delete=models.SET(func),)
        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                    # 如:
                                            - limit_choices_to={'nid__gt': 5}
                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
        db_constraint=True          # 是否在数据库中创建外键约束
        parent_link=False           # 在Admin中是否显示关联数据

ManyToManyField()参数

ManyToManyField(RelatedField)
        to,                         # 要进行关联的表名
        related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
        related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
        limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
                                    # 如:
                                            - limit_choices_to={'nid__gt': 5}
                                            - limit_choices_to=lambda : {'nid__gt': 5}

                                            from django.db.models import Q
                                            - limit_choices_to=Q(nid__gt=10)
                                            - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
                                            - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
        symmetrical=None,           # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
                                    # 做如下操作时,不同的symmetrical会有不同的可选字段
                                        models.BB.objects.filter(...)

                                        # 可选字段有:code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField('self',symmetrical=True)

                                        # 可选字段有: bb, code, id, m1
                                            class BB(models.Model):

                                            code = models.CharField(max_length=12)
                                            m1 = models.ManyToManyField('self',symmetrical=False)

        through=None,               # 自定义第三张表时,使用字段用于指定关系表
        through_fields=None,        # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
                                        from django.db import models

                                        class Person(models.Model):
                                            name = models.CharField(max_length=50)

                                        class Group(models.Model):
                                            name = models.CharField(max_length=128)
                                            members = models.ManyToManyField(
                                                Person,
                                                through='Membership',
                                                through_fields=('group', 'person'),
                                            )

                                        class Membership(models.Model):
                                            group = models.ForeignKey(Group, on_delete=models.CASCADE)
                                            person = models.ForeignKey(Person, on_delete=models.CASCADE)
                                            inviter = models.ForeignKey(
                                                Person,
                                                on_delete=models.CASCADE,
                                                related_name="membership_invites",
                                            )
                                            invite_reason = models.CharField(max_length=64)
        db_constraint=True,         # 是否在数据库中创建外键约束
        db_table=None,              # 默认创建第三张表时,数据库中表的名称

表数据获取

类型获取方式
[obj,obj]对象.all,.filter
[{},{}]字典.values
[(),()]元组.vlaues_list

多数据获取用列表形式表示,比如select标签单选获取为$().val(1),多选为$.val([1,2,3])

数据库中表对象数据获取

需要获取的数据=表对象.表字段名

如:
peo_obj = models.Table.objects.last()   #获取表最后一行数据的对象
peo_id = peo_obj.id                     #获取表数据对象中的id字段值

创建表

models.py

注:不设置id字段列默认自动添加

from 应用名 import models

class 类名(models.Model):
    id=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')    #创建主键,自增长、设置主键、无序列号设置、别名为ID
    字段1=models.CharField("字段1",max_length=20)      #创建字符串字段,最大长度为20,别名为【字段1】
    字段2=models.IntegerField(verbose_name='字段2')    #创建整型字段,别名为【字段2】

setting.py

INSTALLED_APPS = [应用名]

创建生成表

python manage.py makemigrations 应用名
python manage.py migrate

反向创建数据库表

反向创建数据库表(一般用于配置连接好数据库,数据库中已经有数据,但项目中没有models表的已有环境)

python manage.py inspectdb

创建后导出并替代models.py,默认生成路径是项目根目录而不是APP根目录

python manage.py inspectdb > models.py

models 数据操作

增加

在views.py中添加视图函数,要提前引用视图models类

from 应用名.models import 类名                      #引入视图数据库models类

方法一(实例类的对象):

def 函数名(request):
    model对象=类名(字段1="值1",字段2="值2")          #根据字段添加值
    model对象.save()                                 #保存到数据库
    return 返回值

方法二(调用create方法):

def 函数名(request):
    类名.objects.create(字段1="值1",字段2="值2")    #根据字段添加值,并同步到数据库
    return 返回值

字典传输数据增加数据

def 函数名(request):
    类名.objects.create(**kwargs)                      #字典形式传输和添加,字典键对应数据库字段
    return 返回值

删除

调用filter方法查找并删除

def 函数名(request):
    类名.objects.filter(查找字段名="值").delete()
    return 返回值

修改

方法一:(实例对象重新赋值)

def 函数名(request):
    model对象=类名.objects.get(查找字段名="值")     #获取数据对象集合
    model对象.修改字段名="值"                       #修改字段值
    model对象.save()                                #保存到数据库

方法二:(调用filter方法查找并重新赋值)

def 函数名(request):
    models.类名[表名].objects.filter(查找字段名="值").update(要修改的字段名="修改后值")      #查询指定字段所在行,给该行要修改的字段从新赋值
    return 返回值

查询

查询方法

def 函数名(request):
    model对象集合=类名.objects.方法(条件)           #查询条件是可选项,比如使用模糊查询
    model对象=model对象集合[0]                      #查询条件对象集合特定的对象
    对象对应值=model对象.字段名                     #查询对象对应的值
    return 返回值
方法释义
filter(**kwargs)查找内容,值可以是(字段=”值”)也可以泛指字典,包含了与所给筛选条件相匹配的对象
all()显示所有内容,括号内可使用切片,如:all([:3])、all([::2])等
get(**kwargs)返回与所给筛选相匹配的结果,结果只有一个,若没有结果或超过一个抛出异常
values(*field)返回一个ValueQuerySet,一个特殊的QuerySet,运行后并不是一系列model的实例化对象,而是一个可迭代的字典序列
values_list(*field)返回一个ValueQuerySet,一个特殊的QuerySet,运行后并不是一系列model的实例化对象,而是一个元组序列
exclude(**kwargs)包含了与所给筛选条件不匹配的对象
order_by(*field)对查询结果排序
reverse()对查询结果反向排序
distinct()从反向结果中剔除重复记录
count()返回数据库中匹配查询(QuerySet)的对象数量
first()返回第一条记录
last()返回最后一条记录
exists()如果QuerySet包含数据,返回True,否则返回False

查询结果运算

函数释义
Avg(“字段名”)平均值
Sum(“字段名”)求和
Max(“字段名”)求最大值
Min(“字段名”)最小值

示例

from django.db.models import Avg,Sum,Max,Min
models.表名.objects.all().aggregate(Sum('计算的字段'))

模糊查询

类名.objects.filter(查询条件)
查询条件释义
字段=等于
字段__exact=精准查询
字段__gt=大于
字段__gte=大于等于
字段__contains=模糊匹配(区分大小写)
字段__icontains=模糊匹配(不区分大小写)
字段__in=包含icontains
字段__isnull=是否为空
字段__lt=小于
字段__lte=小于等于
字段__range=范围

执行原生SQL语句

from django.db import connection

def my_custom_sql(self):
    with connection.cursor() as cursor:
        cursor.execute("执行sql语句",)
        #查出一条数据
        row = cursor.fetchone()
        #查出所有数据
        #row = cursor.fetchall()
    return row

综合示例

示例所用方法较少,可根据示例环境自行测试各个方法

架构

Mydiango
    APP
        migrations
            0001_initial.py
            __init_.py
        templates
            __init__.py
            index.html
        admin.py
        apps.py
        models.py
        tests.py
        views.py
    Mydiango
        settings.py
        urls.py
        wsgi.py
    manage.py

创建项目和APP

django-admin startproject Mydjango
cd Mydjango
python manage.py startapp APP

示例配置

setting

INSTALLED_APPS 添加APP[以前存在的勿删]

'APP',

MYSQL配置数据库连接

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydata',
        'USER': 'mydata',
        'PASSWORD': 'Abc123',
        'HOST': '192.168.88.80',
        'POST': '3306',
    }
}

SQLService配置数据库连接

DATABASES = {
  'default': {
    'NAME': 'screen',
    'ENGINE': 'sql_server.pyodbc',
    'HOST': '127.0.0.1',
    'PORT': '1433',
    'USER': 'user',
    'PASSWORD': 'password',
    'OPTIONS':{
      'driver':'SQL Server Native Client 10.0',
    }
  }
}

TEMPLATES 添加静态文件存放目录路径[以前存在的勿删]

'DIRS': [os.path.join(BASE_DIR, 'APP/templates')],

init.py

在项目全局设置 Mydjango -> Mydjango -> __init__.py 中设置使用pymysql连接数据库

import pymysql

pymysql.install_as_MySQLdb()

urls.py

# coding=utf8
from django.contrib import admin
from django.urls import path,re_path
from APP import views


urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^$',views.Index),
    path('add/', views.Add_data),           # url【add】添加 --- 对应 ---- 添加视图函数【Add_data】
    path('delete/', views.Del_data),        # url【delete】删除 --- 对应 ---- 删除视图函数【Del_data】
    path('update/', views.Up_data),         # url【update】更新 --- 对应 ---- 更新视图函数【Up_data】
    path('select/', views.Sel_data),        # url【select】查询 --- 对应 ---- 查询视图函数【Sel_data】
]

views.py

# -*- coding:utf8 -*-
from django.shortcuts import render,HttpResponse
import datetime
from APP.models import Animal_Table

def Index(request):                                                 #网站默认首页
    return render(request,"index.html",locals())

def Add_data(request):                                              #添加数据函数
    Animal_Table.objects.create(Type="森林",Name="松鼠",Li_ID=1)                  # 根据字段添加值,并同步到数据库
    Animal_Table.objects.create(Type="森林",Name="老虎",Li_ID=1)
    Animal_Table.objects.create(Type="海洋",Name="鲸鱼",Li_ID=2)
    Animal_Table.objects.create(Type="海洋",Name="海龟",Li_ID=2)
    return HttpResponse("添加成功")

def Del_data(request):                                              #删除数据函数
    Animal_Table.objects.filter(Name="鲸鱼").delete()                             # 根据字段查找,并删除对应行
    return HttpResponse("删除成功")

def Up_data(request):                                              #更新数据函数
    Animal_Table.objects.filter(Name="老虎").update(Type="猪圈")                  # 查询指定字段所在行,给该行要修改的字段从新赋值
    return HttpResponse("更新成功")

def Sel_data(request):                                             #查询数据函数
    Obj_Mut = Animal_Table.objects.all()                                          # 获取对象集合
    print("对象集合:",Obj_Mut)
    
    Obj_One = Obj_Mut[1]                                                          # 获取特定的对象
    print("集合中的对象:",Obj_One)
    
    Obj_Pro = Obj_One.Type                                                        # 获取特定的对象字段值【类型】
    print("对象对应值-类型:",Obj_Pro)
    
    Obj_Name = Obj_One.Name                                                        # 获取特定的对象字段值【名字】
    print("对象对应值-姓名:",Obj_Name)
    
    sel_num = Animal_Table.objects.count()                                         # 获取查询出来的所有数量
    print("查询数量为:",sel_num)
    return HttpResponse(Obj_Pro,Obj_Name)

models.py

# -*- coding:utf8 -*-
from django.db import models

##########################################    创建表    #########################################
class Animal_Table(models.Model):
    Type=models.CharField(max_length=20)            #创建字符串字段,最大长度为20
    Name=models.CharField(max_length=20)            #创建字符串字段,最大长度为20
    Li_ID=models.IntegerField()                     #创建整型字段

    def __str__(self):                              #类str方法,用于调取显示字符串而不是内存地址
        return self.Name

apps.py

from django.apps import AppConfig

class AppConfig(AppConfig):
    name = 'APP'

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <a href="/add/">添加数据</a>
    <a href="/delete/">删除数据</a>
    <a href="/update/">更改数据</a>
    <a href="/select/">查询数据</a>
</div>
</body>
</html>

数据库生成

执行完成后 项目 migrations 会生成数据库变更文件,本示例生成文件为0001_initial.py

python manage.py makemigrations APP
python manage.py migrate

运行测试

运行服务

python manage.py runserver 8000

测试需要访问 http://127.0.0.1:8000 测试

    原文作者:数据库基础
    原文地址: https://my.oschina.net/u/2924779/blog/2049172
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞