首页 > 解决方案 > Django admin.site.register 为模型类抛出 TypeError

问题描述

这是这个问题的后续问题。

我想自动从 djangomodels.py文件中导入类,然后使用admin.site.register(). 这是我的代码:

from django.contrib import admin
import inspect
from . import models 

for name, obj in inspect.getmembers(models):
    if inspect.isclass(obj):
        admin.site.register(obj)

此代码抛出一个TypeError: 'type' object is not iterable.

OP将此问题标记为已回答,并且我发现了其他几个显示此代码的示例。我还查看了此处的文档,没有看到任何表明这是错误的东西。

完整追溯:

Bills-MacBook-Pro:Pro billarmstrong$ python manage.py runserver/anaconda3/lib/python3.6/site-packages/django/db/models/base.py:309:RuntimeWarning: Model 'ProWP.p_item' was already registered. Reloading models is not advised as it can lead to inconsistencies, most notably with related models.  new_class._meta.apps.register_model(new_class._meta.app_label, new_class)/anaconda3/lib/python3.6/site-packages/django/db/models/base.py:309:RuntimeWarning: Model 'ProWP.p_item' was already registered. Reloading models is not advised as it can lead to inconsistencies, most notably with related models.
  new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x108f1dea0>
Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/django/utils/autoreload.py", line 225, in wrapper
    fn(*args, **kwargs)
  File "/anaconda3/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 112, in inner_run
    autoreload.raise_last_exception()
  File "/anaconda3/lib/python3.6/site-packages/django/utils/autoreload.py", line 248, in raise_last_exception
    raise _exception[1]
  File "/anaconda3/lib/python3.6/site-packages/django/core/management/__init__.py", line 327, in execute
    autoreload.check_errors(django.setup)()
  File "/anaconda3/lib/python3.6/site-packages/django/utils/autoreload.py", line 225, in wrapper
    fn(*args, **kwargs)
  File "/anaconda3/lib/python3.6/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/anaconda3/lib/python3.6/site-packages/django/apps/registry.py", line 120, in populate
    app_config.ready()
  File "/anaconda3/lib/python3.6/site-packages/django/contrib/admin/apps.py", line 23, in ready
    self.module.autodiscover()
  File "/anaconda3/lib/python3.6/site-packages/django/contrib/admin/__init__.py", line 26, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/anaconda3/lib/python3.6/site-packages/django/utils/module_loading.py", line 47, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "/anaconda3/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/billarmstrong/Documents/GitHub/Core/WebDataCollect/Pro/ProWP/admin.py", line 7, in <module>
    admin.site.register(obj)
  File "/anaconda3/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 102, in register
    for model in model_or_iterable:
TypeError: 'type' object is not iterable

第二次后runserver有一个新的警告 - 但这不是原始错误的一部分。我将所有内容都包括在内以供参考。是p_item一个类对象models.py

最终编辑

上面提到的警告是复制类的草率剪切/粘贴的结果。它与原始问题或下面的答案无关。

标签: pythondjangopython-3.xdjango-models

解决方案


猜测一下,不仅有django.db.models.Model导入的类。可能,您的本地models模块包含更多项目,包括其他类(if inspect.isclass通过)。您可能需要执行额外的issubclass(obj, django.models.Model)或类似的检查。

它在链接问题中起作用的事实表明您在本地models.py模块中有其他代码,可能是通过导入(很难注意到)。但是额外检查一下这obj是一个实际的 Django 模型(如上所述),可能比尝试删除那些额外的代码更安全。

总而言之,尝试以下(未经测试):

from django.contrib import admin
from django.db.models import Model
import inspect
from . import models 

for name, obj in inspect.getmembers(models):
    if inspect.isclass(obj) and issubclass(obj, Model):
        admin.site.register(obj)

推荐阅读