Python Django使用外键关系提交多个数据库对象

Python Django使用外键关系提交多个数据库对象,python,django,django-models,django-views,django-orm,Python,Django,Django Models,Django Views,Django Orm,我将Django用于多个数据库。我有一个“预览”数据库,它接收用户上传的消息,这些消息必须由管理员预览并“接受”,此时它们将提交到“默认”生产数据库。下面的视图应该这样做,但我得到了一个错误。每个newSentenceModel对每个newMessageSegment都有一个外键,每个newMessageSegment对每个消息都有一个外键。如果管理员接受内容,我想将每个项目移动到新数据库,然后删除预览数据库中的旧条目。请帮忙!谢谢- 以下是错误: instance is on database

我将Django用于多个数据库。我有一个“预览”数据库,它接收用户上传的消息,这些消息必须由管理员预览并“接受”,此时它们将提交到“默认”生产数据库。下面的视图应该这样做,但我得到了一个错误。每个newSentenceModel对每个newMessageSegment都有一个外键,每个newMessageSegment对每个消息都有一个外键。如果管理员接受内容,我想将每个项目移动到新数据库,然后删除预览数据库中的旧条目。请帮忙!谢谢-

以下是错误:

instance is on database "preview", value is on database "default"
错误消息出现在此行:

newMessageSegment.msg = newMessage # Setup the foreign key to the msg itself
以下是查看功能:

## This view is used when the admin approves content and clicks on the "accept content" button when reviewing 
## a recent upload - it saves the data to the production database
def accept_content(request, msg_id=None):
    if msg_id == None: # If for some reason we got a None, then it's not a valid page to accept so redirect home
        return HttpResponseRedirect("/") # Redirect home
    msgList = Message.objects.using('preview').all() # Get all Messages
    msgSegmentList = MessageSegment.objects.using('preview').all() # Get all MessageSegment Objects
    sentenceModels = SentenceModel.objects.using('preview').all() # Get all SentenceModels
    for msgs in msgList: # Iterate all msgs
        if int(msgs.id) != int(msg_id): # Don't care if it is not the msg needing review
            continue # Short Circuit
        msgPrimaryKey = msgs.pk # Extract the primary key from this msg to restore later
        msgs.pk = None # Erase the primary key so we can migrate databases properly
        newMessage = msgs # This is the msg to transfer to the new one
        newMessage.save(using='default') # Save the item to the production database
        for msgSegment in msgSegmentList: # Iterate all msg segments for this msg
            if msgSegment.msg_id == msgPrimaryKey: # Check the foreign keys on the msg segment to msg connection
                newMessageSegment = msgSegment # Define a new msg segment
                msgSegment.pk = None # Erase the primary key so we can assign it properly
                newMessageSegment.pk = None # Erase the primary key so we can assign it properly
                newMessageSegment.msg = newMessage # Setup the foreign key to the msg itself
                newMessageSegment.save(using='default') # Save the item to the production database
                for sentenceModel in sentenceModels: # Iterate all sentences for this msg segment
                    if sentenceModel.msg_segment_id == msgSegment.id: # Determine which sentences are for this msg segment
                        newSentenceModel = sentenceModel # Define the newSentenceModel
                        newSentenceModel.msg_segment = newMessageSegment # Setup the foreign key to the msg segment
                        newSentenceModel.save(using='default') # Save the item to the production database
                        sentenceModel.delete(using='preview') # Delete the item from the review database
                msgSegment.delete(using='preview') # Delete the item from the review database
        msgs.pk = msgPrimaryKey # Restore the key so we can delete it properly
        msgs.delete(using='preview') # Delete the item from the review database
    return HttpResponseRedirect("/")

Django会记住对象保存时使用的数据库,因此每个
newMessageSegment
仍与
preview
数据库关联,直到您将其保存到
default
,并且正确地禁止跨数据库FK分配。这是未经测试的,但可以将其分配给基础
msg\u id
字段:

newMessageSegment.msg_id = newMessage.id
如果做不到这一点,您可以创建
newMessageSegment
的新副本,而不仅仅是创建对它的新引用。我认为您可以通过迭代
msgSegment.\u meta.fields
来实现自动化,但我可能忽略了继承或其他方面的微妙之处。任何多对多的领域都将是一种痛苦

或者,如果您只是想破解它,请编辑跟踪它的内部对象。我一般不建议这样做,但无论如何,当你保存的时候,它会被改变

newMessageSegment._state.db = "default"
newMessageSegment.msg = newMessage
newMessageSegment.save(using="default")