django-數據庫[ 基本操作 ]


os:mac, django1.9.5,  python3.5

database:mysql

 

 

0.背景

django中每一個模型model都對應於數據庫中的一張表,每個模型中的字段都對應於數據庫表的列。

方便的是,django可以自動生成這些create table, alter table, drop table的操作。

想想看,如果我們每次修改django中的數據模型,又要去同步修改數據庫中的模型,是多么麻煩的一件事。更不用說那些容易發生的細節上的錯誤了。

 

 

1.創建模型

假設我們為一個shopping mall創建一個簡單的數據模型:

商場里分各個區域,如化妝品區,女裝區,男裝區等等。對應Area模型,有字段區域名name, 描述description, 管理人員manager。

接着,在每個區域中又有許多商鋪。對應Store模型,有字段商鋪名name, 外鍵area(Area與Store為一對多關系)。

而每個商鋪里,販賣各種商品。對應Item模型,有字段商品名name, 價格price, 外鍵store(Store與Item為一對多關系)。

 1 from django.db import models
 2 from django.contrib.auth.models import User
 3 
 4 
 5 class Area(models.Model):
 6     name = models.CharField(max_length=30)
 7     description = models.CharField(max_length=100)
 8     manager = models.ForeignKey(User, blank=True, null=True)
 9 
10     def __str__(self):
11         return self.name
12 
13 
14 class Store(models.Model):
15     name = models.CharField(max_length=30)
16     area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='stores')
17 
18     def __str__(self):
19         return self.name
20 
21 
22 class Item(models.Model):
23     name = models.CharField(max_length=30)
24     price = models.IntegerField()
25     store = models.ForeignKey(Store, on_delete=models.CASCADE)
26 
27     def __str__(self):
28         return self.name

 

1.1 主鍵

我們注意到,在上面定義model時,我們並沒有定義主鍵primary key。這是因為除非你顯式指定,django會自動為你的模型增加一個字段名為id的主鍵。

id = models.AutoField(primary_key=True)

當然,我們也可以自定義主鍵,只要給字段設置primary_key=True就可以。這時候,django就不會自動為我們的模型設置id主鍵了。

primary_key=True意味着null=False 以及unique=True。也就是說,主鍵是非空且獨一無二的,它是用來在這個表中標識這一行數據的。

在django的模型中,主鍵也是只讀的。

 

1.2 外鍵

在模型中定義外鍵時,同步數據庫后,django默認在外鍵字段名后加上"_id"作為數據庫表的列名。

ForeignKey()常用的額外參數如下:

級聯刪除: on_delete=models.CASCADE

反向查詢: 如我們在Store模型的外鍵store字段中設置realted_name='stores',可以在關系的另一端,即area端反向查詢到stores

 

1.3 __str__()方法

給每個模型定義__str__()方法是一個很好的做法,這不只是為了交互時方便,也是因為django會在其他一些地方用 __str__() 來顯示對象。

注意__str__()方法必須返回字符串。

 

 

2.生成模型

每一次對model的修改,都需要運行以下兩條命令來同步我們的數據庫:

1 python manage.py makemigrations
2 python manage.py migrate

 

2.1 makemigrations

其中第一條命令的作用是生成migrations文件。

在我們的例子中,makemigrations后shell中會有以下輸出:

1 Migrations for 'shop':
2   0001_initial.py:
3     - Create model Area
4     - Create model Store
5     - Create model Item

而這時候,在我們的app shop中能看到一個migrations文件夾,打開0001_initial.py,就能看到對應的migration語句。

 

2.2 migrate

而第二條命令的作用是將這些migrations應用到數據庫上去。

在我們的例子中,migrate后shell中會有以下輸出:

1 Operations to perform:
2   Apply all migrations: silk, sessions, admin, auth, shop, contenttypes
3 Running migrations:
4   Rendering model states... DONE
5   Applying shop.0001_initial... OK

自動生成的表名為app名(shop)和模型的小寫名稱(area, store, item)的組合(用下划線_組合)。如在app shop下的模型Area對應數據庫中的shop_area表。

 

2.3 說明

每個app的migration文件都會在app中的migrations文件夾下被生成。

在django中,每一次對模型以及模型中的字段的增加,刪除或修改,都會在執行python manage.py makemigrations后生成相應的migrations。

 

建議仔細檢查makemigrations后shell中的輸出,尤其是在對模型進行了復雜的改變時。檢查完畢后再執行migrate。

當然,如果你在運行makemigrations后反悔了,大可以不執行migrate,而是轉去刪除剛剛生成的migrations文件。

everyone deserves a second chance:)

 

 

3.數據庫的基本操作

3.1 增

我們先為shopping mall增加一個化妝品區:

 

1 from django.shortcuts import HttpResponse
2 from .models import Area
3 
4 
5 def add_area(request):
6     area = Area.objects.create(name='cosmetic', description='充滿香味兒的區域')
7 
8     return HttpResponse('added!')

 

其中,第六行代碼 area = Area.objects.create(name='cosmetic', description='充滿香味兒的區域')

所對應的mysql語句為:

insert into shop_area(name,description) values('cosmetic','充滿香味兒的區域');

 

3.2 查

現在,我們來列出shopping mall中的所有區域:

1 from django.shortcuts import HttpResponse
2 from .models import Area
3 
4 
5 def list_area(request):
6     area = Area.objects.all()
7     print(area)                    # 在shell輸出[<Area: 'cosmetic'>],如果沒有定義__str__(),將輸出無意義的[<Area: Area object>]
8 
9     return HttpResponse('listed!')

 

第六行代碼 area = Area.objects.all()

相當於mysql語句:

select * from shop_area;

復習一下:shop_area為django為模型自動生成的表名(app_model)

 

3.3 改

在3.1中,我們並沒有為化妝品區指定管理人員。現在,我們修改化妝品區的信息,將rinka指定為管理人員。

首先,我們要創建一個rinka用戶。這里我將創建一個名為rinka的superuser:

python manage.py createsuperuser

 

接着,將我們創建的rinka用戶指定為化妝品區的管理人員:

 1 from django.shortcuts import HttpResponse
 2 from .models import Area
 3 from django.contrib.auth.models import User
 4 
 5 
 6 def update_area(request):
 7     rinka = User.objects.get(username='rinka')
 8     area = Area.objects.get(id=1)
 9     area.manager = rinka
10     area.save()
11 
12     return HttpResponse('updated!')

 

注意必須調用對象的save()方法,對對象實例的修改才會保存到數據庫中去。這是一個容易出錯的地方。

第8~10行代碼對應的mysql語句為:

update shop_area set manager_id=1 where id=1;

復習一下:manager_id為django默認為外鍵生成的列名(foreignkey_id)

 

3.4刪

刪除操作很簡單,我們現在來刪除數據庫表shop_area中id為1的那行數據:

1 from django.shortcuts import HttpResponse
2 from .models import Area
3 
4 
5 def delete_area(request):
6     area = Area.objects.get(id=1)
7     area.delete()
8 
9     return HttpResponse('deleted!')

 

第6~7行語句對應的mysql語句為:

delete from shop_area where id=1;

 

 


總結

django中數據庫基本操作:

1.同步數據庫

python manage.py makemigrations  #生成migrations

python manage.py migrate   #應用migrations

2.增

Model.objects.create(**kwargs)

3.查

Model.objects.all()

4.改

m = Model.objects.get(id=1)

m.name = 'new_name'

m.save()

5.刪

m = Model.objects.get(id=1)

m.delete()

 


免責聲明!

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



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