私は2つのdjangoプロジェクトを持っています
- リーガルビーグル
- システムモデル
各プロジェクトには、「データソース」アプリケーションがあります。
- リーガルビーグル/データソース
- system_models/データソース
各データソース アプリケーションでは、
- regalbeagle/datasources/models.py
- system_models/datasources/models.py
「データソース」モデルがあります:
class Datasource(models.Model):
fullname = models.CharField(max_length=100)
url = models.URLField()
source_type = SmallIntegerField(default=1)
icon = models.CharField(max_length=255)
def __unicode__(self):
return self.fullname
異なるプロジェクトの同じ名前のアプリケーションに 2 つの同じモデルがある理由については、すぐに説明しますが、最初に、私が見ている奇妙な動作を特定したいと思います。python setup.py install を使用して、system_models プロジェクトをグローバル python lib ディレクトリにインストールしました。ただし、regalbeagle プロジェクト内から python manage.py シェルを実行すると、完全修飾パスを使用しても system_models のデータソース モデルにアクセスできません。
from system_models.datasources.models import Datasource as SystemDatasource
from regalbeagle.datasources.models import Datasource
python inspect モジュールを使用してロードされているファイルを確認すると、次のように表示されます。
inspect.getfile(SystemDatasource)
'/Users/george/svn/regalbeagle/trunk/regalbeagle/../regalbeagle/datasources/models.pyc'
inspect.getfile(Datasource)
'/Users/george/svn/regalbeagle/trunk/regalbeagle/../regalbeagle/datasources/models.pyc'
ただし、対応する regalbeagle クラスがない system_models 内にダミー モデルを作成すると、パスが認識されたように見えます。
from system_models.datasources.models import DummyClass
inspect.getfile(DummyClass)
'/Library/Python/2.6/site-packages/system_models/datasources/models.pyc'
だから私の質問は、フルパスを使用してインポートしたにもかかわらず、Django が system_models の Datasource クラスを regalbeagle のクラスと魔法のように交換する方法です。django が同じ名前の 2 つのアプリケーションを持つことを好まない場合、なぜ私の DummyClass は正常に動作しているように見えるのですか?
最も簡単な修正は、system_models モデル名を明示的に SystemDatasource に変更することのようですが、それはモジュール/パッケージングの目的を無効にしているようです。
だから私の質問は:
Django がこれらのモデルの共存を許可するように指定できる追加情報はありますか? それとも私はSOLですか?
お約束どおり、これら 2 つのバージョンの Datasource が必要な理由の説明:
データベースにデータを書き込む必要があるバックエンド クロール プロセスがあり、パフォーマンス上の理由から、このデータベースを Web アプリケーションとは別にしたいと考えていました。だから私はsystemdbを作成し、これに対してsystem_modelsプロジェクトを同期しました。私の Web アプリケーションは、バックエンド プロセスによってクロールされたデータの集計統計を表示できます。これを行うための情報は、regalbeagle データベースにあります。regalbeagle 内のデータソース テーブルでの結合が必要なクエリがいくつかあります。db 間で結合する方法がないため、regalbeagle には独自のデータソースのコピーがあります。しかし、クロールに関連する情報を更新できるようにする必要もあり、regalbeagle の管理インターフェイスを介して実行しています。つまり、テーブルの system_models バージョンにもアクセスする必要があります。
完全なモデル定義の追加:
regalbeagle/datasources/models.py:
from django.db import models
class LanguageManager(models.Manager):
def filter_by_datasources(self, exclude_datasource_id_list=None):
qs = self.get_query_set().filter(datasource__isnull=False)
if exclude_datasource_id_list:
qs = qs.exclude(datasource__in=exclude_datasource_id_list)
return qs.distinct()
class Language(models.Model):
name = models.CharField(max_length=128)
objects = LanguageManager()
class Meta:
ordering = [ 'name' ]
def __unicode__(self):
return "[%s] %s" % (self.id, self.name)
class DataSourceManager(models.Manager):
def get_query_set(self):
return super(DataSourceManager, self).get_query_set() \
.extra(select={ 'lower_fullname': 'lower(fullname)' }) \
.filter(is_inactive__isnull=True) \
.order_by('lower_fullname')
class DataSource(models.Model):
fullname = models.CharField(max_length=100)
url = models.URLField()
icon = models.URLField(null=True)
language = models.ManyToManyField(Language, null=True)
objects = DataSourceManager()
def __unicode__(self):
return "[%s] %s, %s" % (self.id, self.fullname, self.url)
class DataSourceInactive(models.Model):
datasource = models.OneToOneField(DataSource, null=True, related_name='is_inactive')
def __unicode__(self):
return self.datasource.__unicode__()
system_models/datasources/models.py:
from django.db import models
# DataSource -- these are the different places that we import data
# from.
class DataSource(models.Model):
fullname = models.CharField(max_length=100)
url = models.URLField()
source_type = SmallIntegerField(default=1)
icon = models.CharField(max_length=255)
def __unicode__(self):
return self.fullname