2014-09-24 68 views
0

我有一個現有的帶有兩個表的數據庫,名爲Identities和Accounts,我試圖使用Django ORM進行管理。在Django中更新一對多參考字段也會更新其他對象

身份與賬戶一個一對多的關係,我模仿了兩個表是這樣的:

class Identity(models.Model): 
    class Meta: 
     managed = False 
     db_table = "Identities" 
    i_id = models.AutoField(db_column = "I_ID", primary_key = True) 
    name = models.CharField(db_column = "DisplayName", max_length = 200) 

class Account(models.Model): 
    class Meta: 
     managed = False 
     db_table = "Accounts" 
    name = models.CharField(db_column = "Name", max_length = 200, primary_key = True) 
    identity = models.ForeignKey("Identity", db_column = "I_ID", blank = True, null = True, related_name = "accounts") 

我的問題是,當我更新相關聯的賬戶身份,相關聯的所有帳戶新的標識將切換到新的一個:

old_identity = Identity.objects.create(name = "Old") 
new_identity = Identity.objects.create(name = "New") 
account_1 = Account.objects.create(name = "account_1", identity = old_identity) 
account_2 = Account.objects.create(name = "account_2", identity = old_identity) 

# change the identity for account_1: 
account_1.identity = new_identity 
account_1.save() 

# read account_2 from DB and check identity 
account_2 = Account.objects.get(name = "account_2") 

# identity is now "New" also for account_2! 
print account_2.identity.name 

如果我直接在數據庫中做同樣的更新,只有我更改帳戶的身份變了,沒有關聯身份的所有帳戶,所以這是由Django引入的。

我應該怎樣才能在更改identity字段時更新一個帳戶?

注意:只是要清楚,這兩個引用也在數據庫中更改,這不是數據未刷新或類似的問題。

+0

@danihp:根據您的建議更改了代碼,謝謝。當然,結果是一樣的。 – 2014-09-24 07:19:18

+0

這是兩個模型的完整代碼嗎?你有沒有定製管理器或定義的其他方法? – 2014-09-24 07:27:43

+0

@DanielRoseman:這些模型有更多fieds(電子郵件,域...),但相關的位在那裏。我沒有自定義管理器。在類上定義了一些方法,但即使不調用它們也會出現問題。我認爲這可能與關係的定義有關...... – 2014-09-24 07:41:31

回答

3

從已發佈的相關代碼中檢查問題。發佈代碼運行正常:

創建表:

(venv)[email protected]:~/tmp/lldldl/paolo$ python manage.py migrate 
Operations to perform: 
    Synchronize unmigrated apps: mytest 
    Apply all migrations: admin, contenttypes, auth, sessions 
Synchronizing apps without migrations: 
    Creating tables... 
    Creating table mytest_identity 
    Creating table mytest_account 
    Installing custom SQL... 
    Installing indexes... 
Running migrations: 
    Applying contenttypes.0001_initial... OK 
    Applying auth.0001_initial... OK 
    Applying admin.0001_initial... OK 
    Applying sessions.0001_initial... OK 

運行:

(venv)[email protected]:~/tmp/lldldl/paolo$ python manage.py shell 
Python 2.7.3 (default, Feb 27 2014, 19:58:35) 
[GCC 4.6.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> from mytest.models import Account,Identity 
>>> old_identity = Identity.objects.create(name = "Old") 
>>> new_identity = Identity.objects.create(name = "New") 
>>> account_1 = Account.objects.create(name = "account_1", 
             identity = old_identity) 
>>> account_2 = Account.objects.create(name = "account_2", 
             identity = old_identity) 
>>> 
>>> # change the identity for account_1: 
>>> account_1.identity = new_identity 
>>> account_1.save() 
>>> 
>>> # read account_2 from DB and check identity 
>>> account_2 = Account.objects.get(name = "account_2") 
>>> 
>>> # identity is now "New" also for account_2! 
>>> print account_2.identity.name 
Old 
>>> 

測試使用Django 1.7和sqlite3的。也許一些數據庫觸發器? Post/Pre保存信號?

+0

您可以在兩個語句之間打印所有主鍵。 – fceruti 2014-09-24 08:14:22

+0

當然,在回答中更改您的代碼,我會將其複製到我的shell中。一切準備就緒後給我發一條評論。 – danihp 2014-09-24 08:19:13

+0

@danihp:感謝您抽出寶貴時間來測試這個問題 - 最終它是在其中一個表格上定義的雙主鍵,導致問題... – 2014-09-25 10:40:26