1. 程式人生 > >flask 和django區別--在models設計和資料庫方面

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指定