2013-05-01 59 views
0

如果我有我的models/db.py是這樣的:如何在web2py的數據庫級別創建多列唯一約束?

db.define_table('magazine', Field('name'), Field('description')) 
    db.define_table('subscribe', Field('subscriber', db.auth_user), Field('magazine', db.magazine)) 

而且在controller/default.py

# subscribe callback from view 
@auth.requires_login() 
def subscribe(): 
    mag_id = request.args(0, cast=int) 
    db.subscribe.insert(magazine=mag_id, subscriber=auth.user.id) 

用戶會點擊訂閱按鈕,應該調用回調並插入用戶進入訂閱他正在查看當前雜誌的表格。

我該如何讓訂閱表包含訂閱者和雜誌的獨特組合?已訂閱雜誌的訂閱者不應再次訂閱同一雜誌。

例如,這應該工作:

用戶1,雜誌1
用戶1,雜誌2
用戶2雜誌1

但是,這不應該:

用戶1 ,雜誌1
用戶1,雜誌1

一個解決方案是手動檢查combinat離子已經存在我的控制器內:

def subscribe(): 
    mag_id = request.args(0, cast=int) 
    subscribed = db(db.subscribe.subscriber==auth.user.id)&(db.subscribe.magazine==mag_id)) 

    if len(subscribed) < 1: 
     # Do insert 
    else: 
     # Do nothing, user is already subscribed. 

但是,有沒有更好的方式(最好是在數據庫級別)來做到這一點?我看過使用IS_NOT_IN_DB()可以工作,但似乎只限於使用表單? This thread也表明它不起作用。

回答

0

DAL沒有提供在數據庫中指定多列唯一性約束的方法,但您可以直接在web2py以外的數據庫中執行此操作。但是,您可能仍然希望應用程序中有一些明確的代碼來處理此問題 - 否則數據庫級別的違規將最終生成異常。在這種情況下,你可以簡單地使用.update_or_insert()方法:

db.subscribe.update_or_insert(magazine=mag_id, subscriber=auth.user.id) 

那樣只會讓插入如果與該雜誌和用戶的記錄不存在。

+0

哦,這非常方便。謝謝,這可能會訣竅。 – Bak 2013-05-01 15:35:42