Python 更新Django中的一对多引用字段也会更新其他对象

Python 更新Django中的一对多引用字段也会更新其他对象,python,django,django-models,orm,Python,Django,Django Models,Orm,我有一个现有的数据库,它有两个表,叫做identifications和Accounts,我正试图使用Django-ORM来管理它们 身份与帐户有一对多的关系,我对这两个表进行了如下建模: class Identity(models.Model): class Meta: managed = False db_table = "Identities" i_id = models.AutoField(db_column = "I_ID", primar

我有一个现有的数据库,它有两个表,叫做identifications和Accounts,我正试图使用Django-ORM来管理它们

身份与帐户有一对多的关系,我对这两个表进行了如下建模:

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
字段时,我应该怎么做才能只更新一个帐户


注意:需要澄清的是,数据库中的两个引用也都发生了更改,这不是数据未刷新或类似的问题。

检查已发布的相关代码中的问题。发布的代码按预期运行:

创建表:

(venv)dani@egg-v3:~/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)dani@egg-v3:~/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进行测试。也许是一些数据库触发器?后期/预保存信号?

检查已发布的相关代码中的问题。发布的代码按预期运行:

创建表:

(venv)dani@egg-v3:~/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)dani@egg-v3:~/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进行测试。也许是一些数据库触发器?后期/预保存信号?

检查已发布的相关代码中的问题。发布的代码按预期运行:

创建表:

(venv)dani@egg-v3:~/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)dani@egg-v3:~/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进行测试。也许是一些数据库触发器?后期/预保存信号?

检查已发布的相关代码中的问题。发布的代码按预期运行:

创建表:

(venv)dani@egg-v3:~/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)dani@egg-v3:~/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进行测试。也许是一些数据库触发器?后期/预保存信号?

@danihp:根据您的建议更改了代码,谢谢。结果当然是一样的。这是两个模型的完整代码吗?你有没有自定义的管理器,或者定义了其他的方法?@DanielRoseman:这些模型有更多的领域(电子邮件、域…),但是相关的领域在那里。我没有定制经理。在类上定义了一些方法,但即使我不调用它们,也会出现问题。我认为这可能与关系的定义有关…@danihp:根据您的建议更改了代码,谢谢。结果当然是一样的。这是两个模型的完整代码吗?你有没有自定义的管理器,或者定义了其他的方法?@DanielRoseman:这些模型有更多的领域(电子邮件、域…),但是相关的领域在那里。我没有定制经理。在类上定义了一些方法,但即使我不调用它们,也会出现问题。我认为这可能与关系的定义有关…@danihp:根据您的建议更改了代码,谢谢。结果当然是一样的。这是两个模型的完整代码吗?你有没有自定义的管理器,或者定义了其他的方法?@DanielRoseman:这些模型有更多的领域(电子邮件、域…),但是相关的领域在那里。我没有定制经理。在类上定义了一些方法,但即使我不调用它们,也会出现问题。我认为这可能与关系的定义有关…@danihp:根据您的建议更改了代码,谢谢。结果当然是一样的。这是两个模型的完整代码吗?你有没有自定义的管理器,或者定义了其他的方法?@DanielRoseman:这些模型有更多的领域(电子邮件、域…),但是相关的领域在那里。我没有定制经理。在类上定义了一些方法,但即使我不调用它们,也会出现问题。我认为这可能与关系的定义有关……请打印语句之间的所有主键。当然,在回答中更改代码,我会将其复制到shell中。一切准备就绪后给我发一条评论。@danihp:谢谢你花时间来测试这一点-最终导致问题的是其中一个表上定义的一个双主键…请打印语句之间的所有主键。当然,请在回答中更改代码,我会将其复制到shell中。一切准备就绪后给我发一条评论。@danihp:谢谢你花时间来测试这一点-最终导致问题的是其中一个表上定义的一个双主键…请打印语句之间的所有主键。当然,请在回答中更改代码,我会将其复制到shell中。一切准备就绪后给我发一条评论。@danihp:谢谢你花时间来测试这一点-最终导致问题的是其中一个表上定义的一个双主键…请打印语句之间的所有主键。当然,请在回答中更改代码,我会将其复制到shell中。一切准备就绪后给我发一条评论。@danihp:感谢您花时间来测试这一点-最终导致问题的是其中一个表上定义的双主键。。。