Django:尽管在导入时使用了完整的模块路径,但是引用了错误的模型

时间:2012-12-18 19:53:09

标签: django django-models

我有2个django项目

  • regalbeagle
  • system_models

在每个项目中,我都有一个“数据源”应用程序:

  • regalbeagle /数据源
  • system_models /数据源

在每个数据源应用程序中,

  • regalbeagle /数据源/ models.py
  • system_models /数据源/ 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

我将在一秒钟内了解为什么我在不同项目中的同名应用程序中有两个相同的模型,但首先我想确定我所看到的奇怪行为。我已经使用python setup.py install将system_models项目安装到全局python lib目录中。但是,当从regalbeagle项目中运行python manage.py shell时,即使使用完全限定的路径,我也无法访问system_models的Datasource模型。

from system_models.datasources.models import Datasource as SystemDatasource
from regalbeagle.datasources.models import Datasource

当我使用python检查模块查看正在加载哪个文件时,我看到以下内容:

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'

但是,如果我在system_models中创建一个虚拟模型,其中没有相应的regalbeagle类,则路径似乎被识别出来:

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不喜欢有两个同名的应用程序,为什么我的DummyClass似乎工作正常?

最简单的修复方法似乎是将system_models模型名称明确地更改为SystemDatasource,但这似乎打败了模块/打包的目的。

所以我的问题是:

是否有一些我可以指定的附加信息,以便Django允许这些模型共存?或者我是SOL?

正如所承诺的那样,解释为什么我需要这两个版本的Datasource:

我有一个后端抓取过程,需要能够将数据写入数据库,出于性能原因,我希望这个数据库与我的Web应用程序分开。所以我创建了一个systemdb并同步了我的system_models项目。我的Web应用程序能够查看后端进程抓取的数据的聚合统计信息,并且执行此操作的信息位于regalbeagle数据库中。有些查询需要加入regalbeagle中的数据源表,因为没有办法在dbs之间加入,regalbeagle有自己的Datasource副本。但我还需要能够更新与爬网相关的信息,我正在通过regalbeagle的管理界面进行更新。这意味着我还需要访问那里的system_models版本。

添加完整模型定义:

regalbeagle /数据源/ 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 /数据源/ 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

0 个答案:

没有答案