2014-09-24 75 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