Django admin.site.register генерирует TypeError для класса моделей - PullRequest
0 голосов
/ 27 апреля 2018

Это дополнительный вопрос к этому вопросу.

Я хотел бы автоматизировать импорт классов из файла django models.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.

ОП пометил этот вопрос как ответ, и я нашел несколько других примеров, где представлен этот код. Я также просмотрел документацию здесь и не увидел ничего, что указывало бы, что это неправильно.

Полная трассировка:

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

Окончательное редактирование

Вышеупомянутое предупреждение было результатом небрежного вырезания / вставки, который дублировал класс. Это не имеет отношения к исходному вопросу или ответу ниже.

1 Ответ

0 голосов
/ 27 апреля 2018

По-видимому, импортируются не только 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)
...