Django:尽管在导入时使用了完整的模块路径,但引用的模型是错误的
我有两个django项目 富豪鹰 系统模型 在每个项目中,我都有一个数据源应用程序: 富豪鹰/数据源 系统模型/数据源 在每个数据源应用程序中 regalbeagle/datasources/models.py system_models/datasources/models.py 我有一个数据源模型:Django:尽管在导入时使用了完整的模块路径,但引用的模型是错误的,django,django-models,Django,Django Models,我有两个django项目 富豪鹰 系统模型 在每个项目中,我都有一个数据源应用程序: 富豪鹰/数据源 系统模型/数据源 在每个数据源应用程序中 regalbeagle/datasources/models.py system_models/datasources/models.py 我有一个数据源模型: class Datasource(models.Model): fullname = models.CharField(max_length=100) url = models
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
我将在一秒钟内讨论为什么在不同项目中的同名应用程序中有两个相同的模型,但首先我想确定我看到的奇怪行为。我已经使用python setup.py install将system_models项目安装到全局python lib目录中。但是,在regalbeagle项目中运行python manage.py shell时,即使使用完全限定路径,我也无法访问system_模型的数据源模型
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_模型中创建一个虚拟模型,则路径似乎可以识别:
from system_models.datasources.models import DummyClass
inspect.getfile(DummyClass)
'/Library/Python/2.6/site-packages/system_models/datasources/models.pyc'
所以我的问题是,即使我使用完整路径导入,Django如何神奇地将system_模型中的Datasource类替换为regalbeagle中的Datasource类?如果django不喜欢有两个同名的应用程序,为什么我的DummyClass看起来工作正常
最简单的修复方法似乎是将system_models模型名称显式更改为SystemDatasource,但这似乎违背了模块/打包的目的
所以我的问题是:
我是否可以指定一些附加信息,以便Django允许这些模型共存?还是我是索尔
正如承诺的那样,解释我为什么需要这两个版本的Datasource:
我有一个后端爬网过程,需要能够将数据写入数据库,出于性能原因,我希望该数据库与我的web应用程序分离。因此,我创建了一个systemdb,并将我的system_models项目与此同步。我的web应用程序能够查看由后端进程爬网的数据的聚合统计数据,并且执行此操作的信息位于regalbeagle数据库中。有些查询需要在regalbeagle内的数据源表上进行连接,因为无法跨dbs进行连接,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__()
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
system_models/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__()
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
如果最近对结构/模块进行了任何更改,请尝试删除所有*.pyc文件-名称'*.pyc'-delete感谢Francis-我尝试过,从我的regalbeagle项目中删除了所有的*.pyc文件,并从全局python repo中删除了system_模型,然后使用python setup.py安装重新安装。仍然在观察同样的行为。谢谢丹尼尔的澄清。我已经附上了完整的模型定义-我不相信其中一个是从另一个导入任何东西。这就是为什么我假设在幕后发生了一些神奇的django事件。你有任何导入的地方吗?在system_models项目中没有任何导入的地方。regalbeagle项目中有,但数据源应用程序中没有。当我运行python manage.py shell时,如何判断执行了哪些模型文件?我以为它只会是settings.py,而我的只会导入sys和os.path。