flask 和django區別--在models設計和資料庫方面
對於flask:
pip install flask_sqlalchemy(flask 一般用這個作為關係型資料庫;他簡化了sqlalchemy的操作)可以提供orm和原生的資料庫操作;)
pip install pymysql
配置:
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:[email protected]:3306/database_name
這裡需要注意的是'SQLALCHEMY_DATABASE_URI' 是不能變得;
還有一些關於資料操作上的配置:
1:app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True(每次請求結束之後自動提交資料庫中的改動)
2:app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
3:app.config['SQLALCHEMY_ECHO'] = True (查詢時顯示原始sql語句)
這裡做個簡單的小demo:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] =True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =True
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
#建立models(基於類的方式,flask_sqlalchemy 是ORM(objects-relationship-mapping))
class Roles(db.Models):
# 注意類都是要繼承db.Models的
__table_name ='roles'
id = db.Columns(db.Interger,primary_key=True)
name = db.Columns(db.String(64),unique=True)
us = db.relationship('USER',backref='role')
def __repr__(self):
#顯示一個可讀的字串
return self.name
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, index=True)
email = db.Column(db.String(64),unique=True)
pswd = db.Column(db.String(64))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __repr__(self):
return 'User:%s'%self.name
if __name__ == '__main__':
db.drop_all()
db.create_all()
ro1 = Role(name='admin')
ro2 = Role(name='user')
db.session.add_all([ro1,ro2])
db.session.commit()
us1 = User(name='wang',email='[email protected]',pswd='123456',role_id=ro1.id)
us2 = User(name='zhang',email='[email protected]',pswd='201512',role_id=ro2.id)
us3 = User(name='chen',email='[email protected]',pswd='987654',role_id=ro2.id)
us4 = User(name='zhou',email='[email protected]',pswd='456789',role_id=ro1.id)
db.session.add_all([us1,us2,us3,us4])
db.session.commit()
app.run(debug=True)
關於django的資料庫操作:
django已經自帶ORM操作,不需要再裝;
只需要裝相應資料庫的驅動即可
1:pip install pymysql
2:配置就在settings裡面的DATABASE裡面配置
注意都是大寫,這些都是固定的;
這個時候可以執行一下,執行的時候他會自動去連線資料庫,檢視配置資訊是否正確;
下面也同樣寫一個相同的demo:
與flask不同的是,django不是通過SQLAlchemy(app)生成的db
而是通過django內部的模組來匯入的
from django.db import models
class Roles(models.Model):
id = models.AutoField() #這個通常不用指定,django會自動建立
name = models.CharField(max_length=20,verbose_name='姓名‘)
class User(models.Model):
id = models.AutoField()
name = models.Charfield(max_length=20)
email = models.EmailField()
password = models.CharField()
role_id = models.ForeignKey('BookInfo')
if __name__ == '__main__':
role1 = Roles()
role1.name='bluesli1'
role1.save()
role1 = Roles.object.get(id=1)
user1 = User()
user1.role_id = role1.id
user1.name='bluesli2'
user1.save()
這就大致完成了flask和django的簡單的資料庫操作:
接下來對比一下兩者的區別:
1:在模組models的使用方面
flask是通過SQLAlchemy(app) 生成資料庫models物件的
而django是通過模組匯入的方式進行的:from django.db import models
2:models的建立都是基於類的方式;(ORM方式)
3:都是模型類都是繼承各自的Model;
4:在欄位建立的時候可以看出
flask對欄位的型別說明是在db.Columns(db.String(64)(資料型別))是在內部引數中指明的;也就是說flask將欄位型別和約束是當作方法的引數就行指定的;
django是:models.CharField(max_length=20),是通過相應的方法建立的,對應的約束在方法的引數裡面
接下來說說一個關於外來鍵的一個很大的區別:
flask中:
class Role...
__table_name='roles'
us = db.relationship('User',backref='roles') :這裡需要注意User必須是-一對多關係中多方的類名,而roles可以任意指定,但是最好和型別關;
.......
class User....
__tablename__='user'
role_id = db.column(db.Integer,db.ForeigneKey('roles.id')注意此處roles必須是Roles的表名稱;
而在django中:
role_id = db.ForeignKey('Roles') Roles必須是一對多關係中一方的類名;
下面再來說一下flask欄位和django欄位型別的區別
django:
Django根據屬性的型別確定以下資訊:
- 當前選擇的資料庫支援欄位的型別
- 渲染管理表單時使用的預設html控制元件
- 在管理站點最低限度的驗證
django會為表建立自動增長的主鍵列,每個模型只能有一個主鍵列,如果使用選項設定某屬性為主鍵列後django不會再建立自動增長的主鍵列。
預設建立的主鍵列屬性為id,可以使用pk代替,pk全拼為primary key。
注意:pk是主鍵的別名,若主鍵名為id2,那麼pk是id2的別名。
屬性命名限制:
- 不能是python的保留關鍵字。
- 不允許使用連續的下劃線,這是由django的查詢方式決定的,在第4節會詳細講解查詢。
- 定義屬性時需要指定欄位型別,通過欄位型別的引數指定選項,語法如下:
屬性=models.欄位型別(選項)
欄位型別
使用時需要引入django.db.models包,欄位型別如下:
- AutoField:自動增長的IntegerField,通常不用指定,不指定時Django會自動建立屬性名為id的自動增長屬性。
- BooleanField:布林欄位,值為True或False。
- NullBooleanField:支援Null、True、False三種值。
- CharField(max_length=字元長度):字串。
- 引數max_length表示最大字元個數。
- TextField:大文字欄位,一般超過4000個字元時使用。
- IntegerField:整數。
- DecimalField(max_digits=None, decimal_places=None):十進位制浮點數。
- 引數max_digits表示總位數。
- 引數decimal_places表示小數位數。
- FloatField:浮點數。
- DateField[auto_now=False, auto_now_add=False]):日期。
- 引數auto_now表示每次儲存物件時,自動設定該欄位為當前時間,用於"最後一次修改"的時間戳,它總是使用當前日期,預設為false。
- 引數auto_now_add表示當物件第一次被建立時自動設定當前時間,用於建立的時間戳,它總是使用當前日期,預設為false。
- 引數auto_now_add和auto_now是相互排斥的,組合將會發生錯誤。
- TimeField:時間,引數同DateField。
- DateTimeField:日期時間,引數同DateField。
- FileField:上傳檔案欄位。
- ImageField:繼承於FileField,對上傳的內容進行校驗,確保是有效的圖片。這裡需要注意Image也是字元,所以需要指定max_length;
選項
通過選項實現對欄位的約束,選項如下:
- null:如果為True,表示允許為空,預設值是False。
- blank:如果為True,則該欄位允許為空白,預設值是False。
- 對比:null是資料庫範疇的概念,blank是表單驗證範疇的。
- db_column:欄位的名稱,如果未指定,則使用屬性的名稱。
- db_index:若值為True, 則在表中會為此欄位建立索引,預設值是False。
- default:預設值。
- primary_key:若為True,則該欄位會成為模型的主鍵欄位,預設值是False,一般作為AutoField的選項使用。
- unique:如果為True, 這個欄位在表中必須有唯一值,預設值是False。
Flask:
常用的SQLAlchemy欄位型別
型別名 | python中型別 | 說明 |
---|---|---|
Integer | int | 普通整數,一般是32位 |
SmallInteger | int | 取值範圍小的整數,一般是16位 |
BigInteger | int或long | 不限制精度的整數 |
Float | float | 浮點數 |
Numeric | decimal.Decimal | 普通整數,一般是32位 |
String | str | 變長字串 |
Text | str | 變長字串,對較長或不限長度的字串做了優化 |
Unicode | unicode | 變長Unicode字串 |
UnicodeText | unicode | 變長Unicode字串,對較長或不限長度的字串做了優化 |
Boolean | bool | 布林值 |
Date | datetime.date | 時間 |
Time | datetime.datetime | 日期和時間 |
LargeBinary | str | 二進位制檔案 |
常用的SQLAlchemy列選項
選項名 | 說明 |
---|---|
primary_key | 如果為True,代表表的主鍵 |
unique | 如果為True,代表這列不允許出現重複的值 |
index | 如果為True,為這列建立索引,提高查詢效率 |
nullable | 如果為True,允許有空值,如果為False,不允許有空值 |
default | 為這列定義預設值 |
常用的SQLAlchemy關係選項
選項名 | 說明 |
---|---|
backref | 在關係的另一模型中新增反向引用 |
primary join | 明確指定兩個模型之間使用的聯結條件 |
uselist | 如果為False,不使用列表,而使用標量值 |
order_by | 指定關係中記錄的排序方式 |
secondary | 指定多對多中記錄的排序方式 |
secondary join | 在SQLAlchemy中無法自行決定時,指定多對多關係中的二級聯結條件 |
對比flask和django:
flask:nullable
django:null
flask:index
django:db_index
還有一個是關於字串輸出問題的:
flask:
def __repr__(self):
django:
def __str__(self):python3
def __unicode__(self):python2
還有就是flask對於邊長的欄位型別:String(64)這個有點類似sql欄位指定的方式
而django:models.CharField(max_length=20):通過選項max_length指定