Ser*_*gey 18 mysql django foreign-keys django-models
我有两个不同数据库的2个模型:
数据库是手动创建的,但它不会改变任何东西.
class LinkModel(models.Model): # in 'urls' database
id = models.AutoField(primary_key=True)
host_id = models.IntegerField()
path = models.CharField(max_length=255)
class Meta:
db_table = 'links'
app_label = 'testapp'
def __unicode__(self):
return self.path
class NewsModel(models.Model): # in default database
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=50)
link = models.ForeignKey(LinkModel)
class Meta:
db_table = 'news'
app_label = 'test'
def __unicode__(self):
return self.title
Run Code Online (Sandbox Code Playgroud)
在以下代码之后出现错误
newsItem, created = NewsModel.objects.get_or_create( title="test" )
link = LinkModel.objects.using('urls').get( id=1 )
newsItem.link = link # error!
Cannot assign "<LinkModel: />": instance is on database "default", value is on database "urls"
Run Code Online (Sandbox Code Playgroud)
为什么我不能使用外键和不同数据库的模型?
*Note: this is an extension of Vitaly Fadeev's answer
Due to a desire to keep referential integrity, Django does not allow for foreign keys which span multiple databases: https://docs.djangoproject.com/en/dev//topics/db/multi-db/#limitations-of-multiple-databases. Although this is desired in 99% of all applications, in some cases it is helpful to be able to create such an association in the ORM even if you cannot ensure referential integrity.
我已经创建了一个使用提出的解决方案梗概这里通过维塔利·法捷耶夫包装成Django的ForeignKey的领域的一个子类.此解决方案不需要您修改Django Core文件,而是在您需要的情况下使用此字段类型.
# app1/models.py
from django.db import models
class ClientModel(models.Model)
name = models.CharField()
class Meta:
app_label = 'app1'
# app2/models.py
from django.db import models
from some_location.related import SpanningForeignKey
class WidgetModel(models.Model):
client = SpanningForeignKey('app1.ClientModel', default=None, null=True,
blank=True, verbose_name='Client')
Run Code Online (Sandbox Code Playgroud)
要点可以在这里找到:https://gist.github.com/gcko/de1383080e9f8fb7d208
复制到这里是为了方便访问:
from django.core import exceptions
from django.db.models.fields.related import ForeignKey
from django.db.utils import ConnectionHandler, ConnectionRouter
connections = ConnectionHandler()
router = ConnectionRouter()
class SpanningForeignKey(ForeignKey):
def validate(self, value, model_instance):
if self.rel.parent_link:
return
# Call the grandparent rather than the parent to skip validation
super(ForeignKey, self).validate(value, model_instance)
if value is None:
return
using = router.db_for_read(self.rel.to, instance=model_instance)
qs = self.rel.to._default_manager.using(using).filter(
**{self.rel.field_name: value}
)
qs = qs.complex_filter(self.get_limit_choices_to())
if not qs.exists():
raise exceptions.ValidationError(
self.error_messages['invalid'],
code='invalid',
params={
'model': self.rel.to._meta.verbose_name, 'pk': value,
'field': self.rel.field_name, 'value': value,
}, # 'pk' is included for backwards compatibility
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13233 次 |
| 最近记录: |