3.django Model


django ORM基本配置

django中遵循 Code Frist 的原則,即:根據代碼中定義的類來自動生成數據庫表

1.修改project數據庫配置

(1)settigs.py里面

默認

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

 修改為mysql數據庫:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysql',        #數據庫名字
        'USER': 'root',          #賬號
        'PASSWORD': '123456',      #密碼
        'HOST': '192.168.43.128',    #IP
        'PORT': '3306',                   #端口
    }
}

(2)把模塊改成pymysql

修改project目錄下的init.py

import  pymysql
pymysql.install_as_MySQLdb()

2.創建數據庫表結構文件

對應app目錄下的models.py

(1)生成一個簡單的數據庫表:

from django.db import models

class UseInfo(models.Model):
    username = models.CharField(max_length=32)
    passwd = models.CharField(max_length=64)

# 數據庫默認創建id列 自增 主鍵
# 用戶名列 字符串類型 字符長度

(2)把app名稱加入到settings里面

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'cmdb',          # 系統會加載cmdb下的model.py文件
] 

(3)執行命令生成到數據庫

python manage.py  makemigrations
python manage.py  migrate         # 生成數據表

3.數據庫字段和字段參數

1、models.AutoField  自增列 = int(11)
  如果沒有的話,默認會生成一個名稱為 id 的列,如果要顯示的自定義一個自增列,必須將給列設置為主鍵 primary_key=True。
2、models.CharField  字符串字段
  必須 max_length 參數
3、models.BooleanField  布爾類型=tinyint(1)
  不能為空,Blank=True
4、models.ComaSeparatedIntegerField  用逗號分割的數字=varchar
  繼承CharField,所以必須 max_lenght 參數
5、models.DateField  日期類型 date
  對於參數,auto_now = True 則每次更新都會更新這個時間;auto_now_add 則只是第一次創建添加,之后的更新不再改變。
6、models.DateTimeField  日期類型 datetime
  同DateField的參數
7、models.Decimal  十進制小數類型 = decimal
  必須指定整數位max_digits和小數位decimal_places
8、models.EmailField  字符串類型(正則表達式郵箱) =varchar
  對字符串進行正則表達式
9、models.FloatField  浮點類型 = double
10、models.IntegerField  整形
11、models.BigIntegerField  長整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、!models.IPAddressField  字符串類型(ip4正則表達式)不再使用
13、models.GenericIPAddressField  字符串類型(ip4和ip6是可選的)
  參數protocol可以是:both、ipv4、ipv6
  驗證時,會根據設置報錯
14、models.NullBooleanField  允許為空的布爾類型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  減號、下划線、字母、數字
18、models.SmallIntegerField  數字
  數據庫中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  時間 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串,地址正則表達式
22、models.BinaryField  二進制
23、models.ImageField   圖片
24、models.FilePathField 文件

所有字段...
字段
null               -> db是否可以為空
default            -> 默認值
primary_key        -> 主鍵
db_column          -> 列名
db_index           -> 索引
unique               -> 唯一索引
unique_for_date    ->
unique_for_month
unique_for_year
auto_now            -> 更新時,自動更新為當前時間
auto_now_add        -> 創建時,自動生成時間
choices              -> django admin中顯示下拉框,避免連表查詢
blank             -> django admin是否可以為空
verbose_name      -> django admin顯示字段中文
editable          -> django admin是否可以被編輯
error_messages    -> 錯誤信息欠
help_text         -> django admin提示
validators          -> django
form, 自定義錯誤信息(欠)

所有字段參數...
字段參數

 數據庫基本操作

 1.增加數據

 (1)最常用的方式

from cmdb import models

def userinfo(request):
    models.UseInfo.objects.create(username='derek',passwd='666')
    return HttpResponse('這種最常用')

(2)第二種跟第一種差不多

def userinfo(request):
    # models.UseInfo.objects.create(username='derek',passwd='666')
    # return HttpResponse('這種最常用')
    dicts = {'username':'jack','passwd':'999'}
    models.UseInfo.objects.create(**dicts)
    return HttpResponse('第二種跟第一種差不多')

(3)第三種

def userinfo(request):
    obj = models.UseInfo(username='tom',passwd='333')
    obj.save()
    return HttpResponse('第三種')

2.查詢數據

(1)查詢所有

def select(request):
    result = models.UseInfo.objects.all()
    print(result)   #QuerySetL類型 
    for row in result:
        print(row.id,row.username,row.passwd)
    return HttpResponse('select')

(2)查詢指定字段

def select(request):
    result = models.UseInfo.objects.filter(username='derek')
    if result:
        for row in result:
            print(row.id,row.username,row.passwd)
    return HttpResponse('select')

3.刪除數據

def select(request):
    models.UseInfo.objects.filter(id=3).delete()
    return HttpResponse('select')

4.更新數據

def select(request):
    models.UseInfo.objects.filter(id=2).update(passwd='8888')
    return HttpResponse('select')

 數據庫一對多操作

1.數據表結構

from django.db import models

class UseGroup(models.Model):
    uid = models.AutoField(primary_key=True)   #主鍵,自增
    caption = models.CharField(max_length=32,unique=True)   #唯一索引
    ctime = models.DateField(auto_now_add=True,null=True)   #創建時生成時間
    uptime = models.DateField(auto_now=True,null=True)      #更新時自動更新時間

class UseInfo(models.Model):
    username = models.CharField(max_length=32)
    passwd = models.CharField(max_length=64)
    # 關聯外鍵,生成字段名為user_group_id
    user_group = models.ForeignKey("UseGroup",to_field="uid",default=1)

2.外鍵關聯添加數據

from django.shortcuts import render,HttpResponse
from app01 import models

def add(request):
    ug_obj = models.UseGroup.objects.create(caption = "外鍵數據添加")
    # 把外鍵ug_obj當參數傳入
    models.UseInfo.objects.create(username='derek',passwd='123',user_group=ug_obj)
    return HttpResponse('11')

3.外鍵關聯表操作

from django.shortcuts import render,HttpResponse
from app01 import models

# def add(request):
#     ug_obj = models.UseGroup.objects.create(caption = "外鍵數據添加")
#     # 把外鍵ug_obj當參數傳入
#     models.UseInfo.objects.create(username='derek',passwd='123',user_group=ug_obj)
#     return HttpResponse('11')

def ormadd(request):
    models.UseInfo.objects.create(username='jack',passwd='456')
    return HttpResponse('22')

def ormgroup(request):
    models.UseGroup.objects.create(caption='CEO')
    return HttpResponse('33')

def userinfo(request):
    obj = models.UseInfo.objects.all().first()
    print(obj.id,obj.username,obj.user_group_id)
    print(obj.user_group.uid,obj.user_group.caption)
    return HttpResponse('44')

返回結果:

 4.跨表查詢使用雙下划綫 "__"

from django.db import models

class Business(models.Model):
    caption = models.CharField(max_length=32)
    code = models.CharField(max_length=32,null=True,default='QA')

class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=32,db_index=True)
    ip = models.GenericIPAddressField(protocol='ipv4',db_index=True)
    port = models.IntegerField()
    b = models.ForeignKey(to='Business',to_field='id')

獲取表單數據

from django.shortcuts import render,HttpResponse
from app01 import models

def home(request):
    v2 = models.Host.objects.filter(nid=1).values('nid','hostname','b_id','b__caption')
    print(v2)
    return HttpResponse('33')

<QuerySet [{'nid': 1, 'hostname': 'c1.com', 'b_id': 1, 'b__caption': '運維'}]>

 實例(一) 模板中顯示數據庫內容的方法

 創建數據庫

from django.db import models
from django.db import models

class Business(models.Model):
    caption = models.CharField(max_length=32)
    code = models.CharField(max_length=32)

class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=32,db_index=True)
    ip = models.GenericIPAddressField(protocol='both',db_index=True)
    port = models.IntegerField()
    business = models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>業務線列表(對象)</h1>
    <ul>
        {% for row in v1 %}
            <li>{{ row.id }}-{{ row.caption }}-{{ row.code }}</li>
        {% endfor %}
    </ul>

    <h1>業務線列表(字典)</h1>
    <ul>
        {% for row2 in v2 %}
            <li>{{ row2.id }}-{{ row2.caption }}</li>
        {% endfor %}
    </ul>



</body>
</html>
business.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>主機列表(對象)</h1>
    <table border="1">
        <tread>
            <tr>
                <th>主機ID</th>
                <th>IP</th>
                <th>端口</th>
                <th>業務線名稱</th>
            </tr>
        </tread>
        <tbody>
            {% for row in v1 %}
                <tr>
                    <td>{{ row.hostname }}</td>
                    <td>{{ row.ip }}</td>
                    <td>{{ row.port }}</td>
                    <td>{{ row.business.caption }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>

    <h1>主機列表(字典)</h1>
    <table border="1">
        <tread>
            <tr>
                <th>主機ID</th>
                <th>主機名</th>
                <th>業務線ID</th>
                <th>業務線名稱</th>
            </tr>
        </tread>
        <tbody>
            {% for row in v2 %}
                <tr>
                    <td>{{ row.nid }}</td>
                    <td>{{ row.hostname }}</td>
                    <td>{{ row.business__id }}</td>
                    <td>{{ row.business__caption }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>

    <h1>主機列表(元祖)</h1>
    <table border="1">
        <tread>
            <tr>
                <th>主機ID</th>
                <th>主機名</th>
                <th>業務線ID</th>
                <th>業務線名稱</th>
            </tr>
        </tread>
        <tbody>
            {% for row in v3 %}
                <tr>
                    <td>{{ row.0 }}</td>
                    <td>{{ row.1 }}</td>
                    <td>{{ row.2 }}</td>
                    <td>{{ row.3 }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>
host.html
from django.shortcuts import render,HttpResponse
from app01 import models

def business(request):
    # 第一種方式(是個對象)
    v1 = models.Business.objects.all()
    # 第二種方式,只取id和caption(是個字典)
    v2 = models.Business.objects.all().values('id','caption')
    return render(request,'business.html',{'v1':v1,'v2':v2})

def host(request):
    #總共三種方式,對象,字典,列表
    v1 = models.Host.objects.all()
    v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','business__id','business__caption')
    v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','business__id','business__caption')
    return render(request,'host.html',{'v1':v1,'v2':v2,'v3':v3})

 實例(二)  一對多

 1.創建

from django.db import models

class UserType(models.Model):
    title = models.CharField(max_length=32)

class UserInfo(models.Model):
    name = models.CharField(max_length=16)
    age = models.IntegerField()
    ut = models.ForeignKey('UserType')
from django.shortcuts import render,HttpResponse
from app01 import models

def add(request):
    models.UserType.objects.create(title='普通用戶')
    models.UserType.objects.create(title='黃金用戶')
    models.UserType.objects.create(title='白金用戶')

    models.UserInfo.objects.create(name='aa', age=18, ut_id=1)
    models.UserInfo.objects.create(name='bb', age=18, ut_id=2)
    models.UserInfo.objects.create(name='cc', age=18, ut_id=2)
    return HttpResponse('ok')

2.操作

(1)查詢所有用戶和類型

def op(request):
    obj = models.UserInfo.objects.all()
    for row in obj:
        print(row.name,row.age,row.ut.title)
    return HttpResponse('ok')

#查看所有
aa 18 普通用戶
bb 18 黃金用戶
cc 18 黃金用戶

#查看第一條
obj = models.UserInfo.objects.all().first()
print(obj.name, obj.age, obj.ut.title)

aa 18 普通用戶

 (2)查詢所有類型為“黃金用戶的”用戶

正向查

#這里跨表查詢要用到雙下划線"__"
result = models.UserInfo.objects.filter(ut__title='黃金用戶') for item in result: print(item.name,item.age,item.ut.title) 結果: bb 18 黃金用戶 cc 18 黃金用戶

反向查

obj = models.UserType.objects.get(id=2)
    result = obj.userinfo_set.all()
    #這里的userinfo_set相當於models.UserInfo.objects.filter(ut="黃金用戶")
    for item in result:
        print(item.name,item.age,item.ut.title)

結果:
bb 18 黃金用戶
cc 18 黃金用戶

還可以加條件過濾

obj = models.UserType.objects.get(id=2)
    result = obj.userinfo_set.filter(name='bb')
    #這里的userinfo_set相當於models.UserInfo.objects.filter(ut="黃金用戶")
    for item in result:
        print(item.name,item.age,item.ut.title)


結果:
bb 18 黃金用戶

  數據庫多對多操作

 1.自動方式創建第三張表

(1)創建管理用戶和主機兩張表,自動生成第三張關系表

from django.db import models

class Host(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()

class HostAdmin(models.Model):
    username = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    host = models.ManyToManyField('Host')  

(2)添加主機信息和管理用戶信息

#添加主機信息
def add_host(request):
    models.Host.objects.create(hostname='host1',port=80)
    models.Host.objects.create(hostname='host2',port=80)
    models.Host.objects.create(hostname='host3',port=80)
    models.Host.objects.create(hostname='host4',port=80)
    return HttpResponse('ok')

#添加管理用戶信息
def add_hostadmin(request):
    models.HostAdmin.objects.create(username='aa',email='11.com')
    models.HostAdmin.objects.create(username='bb',email='22.com')
    models.HostAdmin.objects.create(username='cc',email='33.com')
    models.HostAdmin.objects.create(username='dd',email='44.com')
    return HttpResponse('ok')

效果如下:

(3)添加第三張關系表

 正向添加數據

#添加第三張表信息,使管理用戶與主機關聯
def user_info(request):
    # 第一步找到用戶
    admin_obj = models.HostAdmin.objects.get(username='bb')
    #第二步找到主機
    host_list = models.Host.objects.filter(id__lt=3)
    #第三步,通過找到的admin_obj對象.add去添加主機
    admin_obj.host.add(*host_list)

    return HttpResponse('ok')

效果如下:

用戶‘’bb“(用戶id=2)就跟主機‘1’和‘2’(主機id=(1,2))關聯起來了

 反向添加數據

def user_info(request):
    host_obj = models.Host.objects.get(id=3)
    admmin_list = models.HostAdmin.objects.filter(id__gt=1)
    host_obj.hostadmin_set.add(*admmin_list)

    return HttpResponse('ok')

效果如下:

總之,不管是正向添加還是反向添加,都是基於主機表或者用戶表的一行數據對應另一張表中的一行或多行數據!

2.手動方式創建第三張表

 (1)創建

手動創建就是告訴django不要自動創建表了

from django.db import models

class HostInfo(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()

class UserMap(models.Model):
    username = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    # through告訴Django用那張表做關聯
    host = models.ManyToManyField(HostInfo, through='HostRelation')

class HostRelation(models.Model):
    host = models.ForeignKey('HostInfo')
    user = models.ForeignKey('UserMap')

效果如下:

(2)添加用戶和主機

from django.shortcuts import render,HttpResponse
from app02 import models

def user_info(request):
    models.HostInfo.objects.create(hostname='host1',port=80)
    models.HostInfo.objects.create(hostname='host2',port=80)
    models.HostInfo.objects.create(hostname='host3',port=80)
    models.HostInfo.objects.create(hostname='host4',port=80)
    models.UserMap.objects.create(username='aa',email='11.com')
    models.UserMap.objects.create(username='bb',email='22.com')
    models.UserMap.objects.create(username='cc',email='33.com')
    models.UserMap.objects.create(username='dd',email='44.com')

    return HttpResponse('ok')

(3)給第三張表添加數據

當使用自定義方式時,第三張關系表數據直接添加就可以,不需要管另外兩張表

def user_info(request):

    models.HostRelation.objects.create(
        host_id = 2,
        user_id = 2
    )
    return HttpResponse('ok')

效果:

  models.HostRelation.objects.create(
        host_id = 1,
        user_id = 1
    )
    models.HostRelation.objects.create(
        host_id=3,
        user_id=1
    )
添加多個

(4)查找

通過自定義方式,查找直接查就可以,不存在正向反向,更方便

def user_info(request):
    relation_list = models.HostRelation.objects.all()
    for item in relation_list:
        print(item.user.username)
        print(item.host.hostname)
    
    return HttpResponse('ok')
結果:
bb
host2
aa
host1
aa
host3
def user_info(request):
    relation_list = models.HostRelation.objects.filter(user__username='bb')
    for item in relation_list:
        print(item.user.username)
        print(item.host.hostname)
    return HttpResponse('ok')

 ORM的F&Q

 1.F

F的作用:用來批量修改數據的

 比如:把上面hostinfo表所有port從80改成90

models.HostInfo.objects.all().update(port=F('port')+10)

要先導入模塊

from django.db.models import F

2.Q

 Q的作用:Q是用來做條件查詢的

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM