【问题标题】:Django not recognizing I have objects in my ModelDjango 没有识别出我的模型中有对象
【发布时间】:2020-05-14 13:46:35
【问题描述】:

在文件MyApp/models/Artwork.py中有一个模型:

class Artwork(models.Model):
    class Meta:
        verbose_name = _('Artwork')
        verbose_name_plural = _('Artworks')

    def __init__(self, *args, **kwargs):
        super(Artwork, self).__init__(*args, **kwargs)

    objects = ArtworkManager()

文件中的一个动作:MyApp/functions/actions.py

from MyApp.models import Artwork

import pprint;

def lock_artwork(request, id):
    pprint.pprint(Artwork)
    try:
        art = Artwork.objects.get(pk=id)
    except ObjectDoesNotExist:
        raise Http404()

MyApp/models/__init__.py:

from .Artwork import Artwork

我的模型中没有属性objects,这是一个奇怪的错误。

堆栈跟踪:

web_1  | <module 'MyApp.models.Artwork' from '/app/MyApp/models/Artwork.py'>
web_1  | Internal Server Error: /en/artwork/lock/2/
web_1  | Traceback (most recent call last):
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
web_1  |     response = get_response(request)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
web_1  |     response = self.process_exception_by_middleware(e, request)
web_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
web_1  |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
web_1  |   File "/app/MyApp/functions/actions.py", line 72, in lock_artwork
web_1  |     art = Artwork.objects.get(pk=id)
web_1  | AttributeError: module 'MyApp.models.Artwork' has no attribute 'objects'

我遗漏了什么明显的东西?

【问题讨论】:

  • 您的模型不属于MyApp/models/Artwork.py,但属于MyApp/models.py。然后您的导入实际上导入了该模型,而不是包含它的虚假模块。
  • @schwobaseggl 这不是一个好主意,我有 10 个模型,这会导致文件非常大。一切正常,但不是这个小东西。根据其他答案,将模型分成自己的文件是没有问题的。
  • @DanielW。可能重复或在此处回答:stackoverflow.com/a/5534251/12581324,请记住检查文档以获取该代码的较新版本,因为答案已经 5 岁了。
  • 你应该改用这个from MyApp.models.Artwork import Artwork
  • 你真正应该做的是保持你的模型独立和可读:从你的子模块中导入它们models/__init__.py。在其他任何地方,直接从models 导入它们。但是NOT 将子模块命名为与模型相同。这将导致名称冲突。

标签: python django django-models


【解决方案1】:

要让 Django 的所有自动魔法(迁移、模型加载……)工作,模型必须位于其应用程序的 models 的命名空间中!无论是普通模块还是包都没有关系。我们经常在一个应用程序的不同模块中分离模型的做法如下:

MyApp
    models
        __init__.py
        artwork  # not the name of any model inside it!
        other

__init__.py 中,您可以从子模块中导入所有模型:

# __init__.py
from .artwork import Artwork
from .other import OtherModel, YetAnotherModel

这样,models.Artwork 解析为实际模型,并被 django 的所有内部魔法所接受。您现在还可以在代码中的任何位置直接导入 Artwork 模型 from MyApp.models

# e.g. some views.py
from MyApp.models import Artwork

附带说明:一个文件中的 10 个模型并不多。如果有明确的语义分离并且没有循环引用,我只会分裂(在这种情况下,您可以争论从单独的应用程序开始)。如果文件中的数十个模型和数百行应该是一个问题,您可能需要寻找更好的 IDE ;-)

【讨论】:

  • 让我感到困惑的是:我上面的代码有一个地方出错,但在所有其他地方都没有问题,代码在 Django 中运行。
  • 示例:这是有效的latest_state = ArtworkState.objects.filter(artwork=obj).latest(),但这不是art = Artwork.objects.get(pk=id);两个模型(Artwork 和 ArtworkState)以相同的方式位于同一文件夹中,具有相同的命名模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-07
  • 2016-06-05
  • 2015-11-29
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 2017-02-10
相关资源
最近更新 更多