【问题标题】:Trouble importing model from other app with Django使用 Django 从其他应用程序导入模型时遇到问题
【发布时间】:2012-05-15 09:58:48
【问题描述】:

我在尝试从其他应用导入模型时遇到问题。我有两个应用程序“主要”和“管理”。这里是代码,我去掉了一些冗长的描述:

“行政”模式:

from django.db import models
from django import forms
from django.forms import ModelForm


class Contract(models.Model):
    Code = models.CharField(max_length=50)
    Provider = models.CharField(max_length=30)
    Description = models.CharField(max_length=30)
    ActivationDate = models.DateField(blank=True, null=True)
    EndingDate = models.DateField(blank=True, null=True)
    Note = models.TextField(blank=True)
    Numbers = models.ManyToManyField('main.Number', through='Crefcontr2num')

def __unicode__(self):
    return u'%s %s' % (self.Provider, self.Description)

class Crefcontr2num(models.Model):
    Dateto = models.DateField()
    Datefrom = models.DateField()
    Contract = models.ForeignKey('Contract')
    Num = models.ForeignKey('main.Number')

“主要”模型:

from django.db import models
from endusers.models import OrderedEndUser
from django import forms
from django.forms import ModelForm, Textarea, TextInput, HiddenInput
#from administrative.models import Contract

class Device(models.Model):
    Maker = models.CharField(error_messages={'required': 'need !'})
    Model = models.CharField(max_length=30, blank=True)
    Imei = models.CharField(max_length=15, unique=True)
    Note = models.TextField(blank=True)
    ActiveState = models.BooleanField()
    AcquisitionDate = models.DateField(blank=True, null=True)
    DismissionDate = models.DateField(blank=True, null=True)
    CodInv = models.CharField(max_length=15, blank=True)
    FK_Enduser = models.ForeignKey('endusers.OrderedEndUser',unique=False, blank=True, null=True, on_delete=models.SET_NULL)
    #   FK_Contract = models.ForeignKey(administrative.Contract, unique=False, blank=True, null=True, on_delete=models.SET_NULL)

...请注意“#”在导入和模型“设备”中的 FK_Contract 前面,如果我只是尝试导入(不带 #)模型合同,我会收到此错误:

Unhandled exception in thread started by <bound method Command.inner_run of <django.contrib.staticfiles.management.commands.runserver.Command object at 0xb6f69a6c>>
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/runserver.py", line 88, in inner_run
self.validate(display_num_errors=True)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 249, in validate
num_errors = get_validation_errors(s, app)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/validation.py", line 35, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 146, in get_app_errors
self._populate()
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 61, in _populate
self.load_app(app_name, True)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 78, in load_app
models = import_module('.models', app_name)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/media/truecrypt1/develope/Django-1.3.1/dbMobile/../dbMobile/main/models.py", line 5, in <module>
from administrative.models import Contract #, Crefcontr2num
File "/media/truecrypt1/develope/Django-1.3.1/dbMobile/administrative/models.py", line 28, in <module>
class ContractForm(ModelForm):
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 205, in __new__
opts.exclude, opts.widgets, formfield_callback)
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 159, in fields_for_model
formfield = f.formfield(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 1155, in formfield
'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to)
AttributeError: 'str' object has no attribute '_default_manager'

到目前为止,我到处寻找并尝试了很多选项..但错误仍然存​​在...我无法理解...我阅读了有关循环导入等...并尝试使用路径引用(如您所见),但效果不佳...

感谢任何建议... 谢谢

【问题讨论】:

    标签: python django model import


    【解决方案1】:

    您的回溯显示错误与您在第 28 行的 administrative/models.py 中定义的类 ContractForm 相关

    ...
    File "/media/truecrypt1/develope/Django-1.3.1/dbMobile/../dbMobile/main/models.py", line 5, in <module>
    from administrative.models import Contract #, Crefcontr2num 
    File "/media/truecrypt1/develope/Django-1.3.1/dbMobile/administrative/models.py", line 28, in <module> 
    class ContractForm(ModelForm):
    ...
    

    由于您没有在问题中包含这部分代码,因此我无法告诉您更多信息。 但是,您应该知道 Python 中的导入是如何工作的。当你使用

    from administrative.models import Contract
    

    Python 不只是从administrative/models.py 文件中选择一个类。相反,Python 解释器读取整个文件,创建模块对象,在新模块命名空间中执行导入文件中的代码,然后将名称 Contract 从新模块的命名空间复制到当前命名空间。因此,尽管您似乎只从模块中导入了一个类,但该模块中的 anywhere 错误可能会阻止成功导入 - 在您的情况下,这是 ContractForm 类的错误。回溯的其余部分详细说明了该类究竟出了什么问题。

    【讨论】:

    • thx Michał Modzelewski...您已经解决了问题...不幸的是,在我的道路中间,我遇到了两个或更多问题...我错过了重点!似乎问题出在多对多领域...再次让我找到正确的问题,并且在导入概念上记得很清楚...
    【解决方案2】:

    如果我没记错的话。如果您正在导入合同模型,并且这两个应用程序似乎保存在应用程序文件夹中,因此您必须在导入时添加应用程序

    from apps.administrative.models import Contract
    

    你应该像下面这样直接使用这个模型

    FK_Contract = models.ForeignKey(Contract, unique=False, blank=True, null=True, on_delete=models.SET_NULL)
    

    【讨论】:

    • 是的,但是...如果我以这种方式尝试,我会收到此错误:“ FK_Contract = models.ForeignKey(Contract, unique=False, blank=True, null=True, on_delete=models .SET_NULL) NameError: name 'Contract' is not defined"
    • ..所以如果我尝试导入合同我必须导入对象模型合同(注意没有引号),但是如果我尝试直接使用路径'administrative.Contract'显式密钥我得到相同错误发布...
    • @Alessio Tomelleri 我正在更新答案
    • 我有文件夹项目“dbMobile”,它的每个应用程序的内部子文件夹为:“管理”和“主要”......对于我里面的每个应用程序:models.py e 视图。 py ...
    • 在导入语句之前加上项目名称是一种不好且不必要的做法。 Python 应用程序是可重用的。如果你这样做,那么如果不编辑所有导入,你就无法安装该应用程序。
    【解决方案3】:

    我只是希望您在此问题中发布的代码中的缩进问题实际上不会发生在您的真实代码中。

    例如,您的administrative/models.py 应如下所示:

    class Contract(models.Model):
        Code = models.CharField(max_length=50)
        Provider = models.CharField(max_length=30)
        Description = models.CharField(max_length=30)
        ActivationDate = models.DateField(blank=True, null=True)
        EndingDate = models.DateField(blank=True, null=True)
        Note = models.TextField(blank=True)
        Numbers = models.ManyToManyField('main.Number', through='Crefcontr2num')
    
        def __unicode__(self):
            return u'%s %s' % (self.Provider, self.Description)
    
    class Crefcontr2num(models.Model):
        Dateto = models.DateField()
        Datefrom = models.DateField()
        Contract = models.ForeignKey('Contract')
        Num = models.ForeignKey('main.Number')
    

    一些提示:

    1. 请勿将模型字段命名为大写。 Python 的最佳实践是date_todate_fromcontract 等等。检查PEP 8 for details
    2. 在 ForeignKey 字段前面加上“FK_”也是一种不好的做法。只是多余的。当然这只是我的看法。也许你正在使用一些命名标准......但如果你能避免这种情况,那就更好了。
    3. verbose_name 参数添加到您的字段定义中。
    4. null=True, blank=True 字段添加default 值。
    5. 对模型进行详细说明(给出有意义的名称)。 Crefcontr2num 不好。

    希望对你有帮助。

    【讨论】:

    • 是的,Francisco 你的建议是对的,我必须牢记那... ..谢谢
    • 那么,问题不在于缩进吗?那是什么?
    • 不不...不是身份,我希望是 :) ...最后,正如 Michal 所关注的那样,这是由于相同的 models.py 中存在另一个模型形式。我使用 'path.name' 引用它是正确的,但我失去了对模型表单的关注,其中它有一个引用模型的外键,它必须被导入......
    • 请澄清我最后一个“..如果你这样做那么你不能在不编辑所有导入的情况下安装应用程序”首先我说我使用 'appname.model' 而不是 'project.appname.model' 格式,已经澄清了......所以这就是我现在无法“删除”关于应用程序的导入语句的原因?!那是因为我一开始就开始导入应用程序.. 现在我无法毫无错误地删除?!?我觉得有点奇怪!?我想我也可以在之后更改格式..删除导入语句并使用显式表单 'appname.model'
    • ...实际上我不得不说这是关于 app.model 'endusers.enduser' 发生的事情,我现在无法删除导入语句而不会遇到错误,如果我使用 'appname.model' 代替对象...但这对我来说很奇怪...
    猜你喜欢
    • 2019-04-26
    • 2016-06-11
    • 2013-03-06
    • 1970-01-01
    • 2014-02-01
    • 2011-03-30
    • 2014-09-16
    • 2013-10-16
    • 2017-02-08
    相关资源
    最近更新 更多