English 中文(简体)
外国关键字段不同的数据库。
原标题:Foreign key fields different databases. Django

Is that possible to have model with foreign key fields on different databases? example:

class MultiBDModel(models.Model):
    db1_user = models.ForeignKey(User) # here suppose to be foreign key on `db1`
    db2_user = models.ForeignKey(User) # and here on `db2`

也许可以复制用户 。 应用自定义管理器 。 哪个返回查询设置为 = db1 。

sections. py 中:

DATABASES = {
     default : {
         ENGINE :  django.db.backends.sqlite3 , # Add  postgresql_psycopg2 ,  mysql ,  sqlite3  or  oracle .
         NAME :  db1 ,                      # Or path to database file if using sqlite3.
         USER :   ,                      # Not used with sqlite3.
         PASSWORD :   ,                  # Not used with sqlite3.
         HOST :   ,                      # Set to empty string for localhost. Not used with sqlite3.
         PORT :   ,                      # Set to empty string for default. Not used with sqlite3.
    },

     website : {
         ENGINE :  django.db.backends.sqlite3 , # Add  postgresql_psycopg2 ,  postgresql ,  mysql ,  sqlite3  or  oracle .
         NAME :  db2 ,                      # Or path to database file if using sqlite3.
         USER :   ,                      # Not used with sqlite3.
         PASSWORD :   ,                  # Not used with sqlite3.
         HOST :   ,                      # Set to empty string for localhost. Not used with sqlite3.
         PORT :   ,                      # Set to empty string for default. Not used with sqlite3.              # Set to empty string for default. Not used with sqlite3.
    }
}
最佳回答

不,ORM不能做任何数据库引擎无法做的事情。

问题回答

否。如@ignacio-vazquez-abrams所写,一个模型必须在同一数据库中包含所有字段。


BUT

作为替代办法,你可以使用代用模型将两个不同数据库的模型联系起来。

Aim

一种模型应同时提供 Db1 和 db2 的字段

General trick

  • You have the model ContactMessage from db1, that we will name legacy_db. We suppose you don t want to touch to this model since it comes from another project.
  • Create a proxy model ProxyContactMessage, it has the same attributes than ContactMessage.
  • Use a database router to tell Django where to look in legacy_db for ProxyContactMessage objects.
  • Add a new model ExtendedContactMessage with the fields you would like to add. Declare a OneToOneField with ProxyContactMessage. This data will be saved to your db2 django_db.
  • Your proxy model cannot hold the new fields since it s abstract, but it can have methods that ask the related ExtendedContactMessage object (if any). Add the callables you want.

Example

在您的 legacy_app/models.py 中, db1 legacy_db 的模型是:

class ContactMessage(models.Model):
    subject = models.CharField(max_length=255)
    message = models.TextField()
    created_at = models.DateTimeField()
    created_by = models.CharField(max_length=255)

    class Meta:
        managed = False
        db_table =  contact_message 

    def __unicode__(self):
        return self.subject

因此您在 myapp/ models. py 中创建 :

class ProxyContactMessage(ContactMessage):
    class Meta:
        proxy = True
        verbose_name =  Contact message 
        verbose_name_plural =  Contact messages 

    def add_extension(self):
        e = ExtendedContactMessage(contact_message=self)
        e.save()
        return e

    def mark_as_processed(self):
        try:
            e = self.extendedcontactmessage
        except ExtendedContactMessage.DoesNotExist:
            e = self.add_extension()
        e.mark_as_processed()

    def processed(self):
        return self.extendedcontactmessage.processed

    def processed_at(self):
        return self.extendedcontactmessage.processed_at

class ExtendedContactMessage(models.Model):
    contact_message = models.OneToOneField(ProxyContactMessage)
    processed = models.BooleanField(default=False, editable=False)
    processed_at = models.DateTimeField(null=True, default=None, editable=False)

    def mark_as_processed(self):
        self.processed = True
        self.processed_at = timezone.now()
        self.save()

请注意, Db2 中只保存非抽象模型 Expended ContactMessage , 因为 ProxycontactMessage 是抽象的。

在 < code> sections. py 中,用类别设置 DATABASE_ROUTERS

class LegacyRouter(object):
    """
    A router to control all database operations on models in the
    legacy database.
    """
    def db_for_read(self, model, **hints):
        if model.__name__ ==  ProxyContactMessage :
            return  legacy_db 
        return None
    def db_for_write(self, model, **hints):
        """
        Attempts to write in legacy DB for ContactMessage.
        """
        if model.__name__ ==  ProxyContactMessage :
            return  legacy_db 
        return None

您的默认路由器将全部发送到 db2 。

最后,你可能有一个管理类,比如:

def mark_as_processed(modeladmin, request, queryset):
    for obj in queryset:
        obj.mark_as_processed()
mark_as_processed.short_description = "Mark as processed"

class ProxyContactMessageAdmin(admin.ModelAdmin):
    list_display = (
         subject ,
         message ,
         created_at ,
         created_by ,
         processed ,
         processed_at ,
    )
    actions = (mark_as_processed,)
admin.site.register(ProxyContactMessage, ProxyContactMessageAdmin)

相关:

""Hack" 应用程序名称在Meta





相关问题
How to get two random records with Django

How do I get two distinct random records using Django? I ve seen questions about how to get one but I need to get two random records and they must differ.

Moving (very old) Zope/Plone Site to Django

I am ask to move data from a (now offline) site driven by Plone to a new Django site. These are the version informations I have: Zope Version (unreleased version, python 2.1.3 ) Python Version 2.1....

Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

Flexible pagination in Django

I d like to implement pagination such that I can allow the user to choose the number of records per page such as 10, 25, 50 etc. How should I go about this? Is there an app I can add onto my project ...

is it convenient to urlencode all next parameters? - django

While writing code, it is pretty common to request a page with an appended "next" query string argument. For instance, in the following template code next points back to the page the user is on: &...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...