Django基礎-Model數據庫操做

表數據操做簡介

表數據操做主要包含對數據和表的增刪改查,表類型有單表,一對多類型表和多對多類型表。html

建立表數據

表數據 代指
類名 生成數據庫表名
類中models.字段類型 生成數據庫字段
models.OneToOneField 一對一
models.ForeignKey 一對多表
models.ManyToManyField 多對多表

OneToOneField()參數python

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()參數mysql

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()參數sql

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])數據庫

數據庫中表對象數據獲取

須要獲取的數據=表對象.表字段名django

如:
peo_obj = models.Table.objects.last()   #獲取表最後一行數據的對象
peo_id = peo_obj.id                     #獲取表數據對象中的id字段值

建立表

models.py架構

注:不設置id字段列默認自動添加app

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 測試

相關文章
相關標籤/搜索