Django无法导入名称(型号)

时间:2017-02-06 17:12:40

标签: python django caching

我在这个应用程序下有两个文件搞乱了。一个更新缓存,另一个是models.py文件。出于某种原因,我得到ImportError: cannot import name 'Cache'每当我尝试加载服务器时。将Cache定义移到NavigationItem定义之上适用于一次测试启动,但每次都失败。

navbar/models.py

from django.db import models
from navbar.generator import update_navigation
from datetime import datetime
import logging


class NavigationItem(models.Model):
    # The title used in the navar
    title = models.CharField(max_length=25, blank=False)
    # The dir it points to
    dir = models.ForeignKey('library.Dir', blank=True, null=True)
    # The level above it
    previous_level = models.ForeignKey('NavigationItem', on_delete=models.SET_NULL, null=True, blank=True)
    # Is it on the top level
    top_level = models.BooleanField(default=False)
    # Shortcut
    show_all_subdirs = models.BooleanField(default=False)
    # position on the list
    position = models.SmallIntegerField(default=15)
    # last modified:
    last_modified = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

    def __repr__(self):
        return "({}) {}".format(self.pk, self.title)

    def save(self, *args, **kwargs):
        super(NavigationItem, self).save(*args, **kwargs)
        logging.INFO("Saved Navbar at " + datetime.now())
        update_navigation()


class Cache(models.Model):
    key = models.CharField(max_length=10, default="key", unique=True)
    data = models.TextField()
    timestamp = models.DateTimeField(auto_now=True)

navbar/generator.py

from navbar.models import Cache, NavigationItem
from datetime import datetime
import logging


def render_navigation():
    query = Cache.objects.filter(key="nav")
    if query.count() > 0:
        return query[0].data
    else:
        return update_navigation()


def update_navigation():
    # Strings used in the generation of templates
    dropdown = '''<li>
                <a class="dropdown-toggle" data-toggle="dropdown" href="{}">{} <span class="caret"></span></a>
                <ul class="dropdown-menu">
                    {}
                </ul>
            </li>
            '''
    link = '<li><a href="{}">{}</a></li>'

    # inner functions
    def generate_navigation(navigation_items):
        # The string to be returned
        result = ""
        # for every item in the list that we get
        for item in navigation_items:
            # if the item points somewhere get the path otherwise make a hash
            path = item.dir.path if item.dir else "#"
            # if it has sub-navigation items
            if item.navigationitem_set.count() > 0:
                # the query below will get all the navigation items under this one sorted properly
                query = item.navigationitem_set.all().order_by('position')
                result += dropdown.format(path, item.title, generate_navigation(query))
            elif item.show_all_subdirs and item.dir is not None:
                result += render_subdirs(item.dir)
            else:
                result += link.format(path, item.title)
        return result

    def render_subdirs(directory):
        result = ""
        for folder in directory.dir_set.all().order_by('title'):
            if folder.dir_set.count() > 0:
                result += dropdown.format(folder.path, folder.title, render_subdirs(folder))
            else:
                result += link.format(folder.path, folder.title)
        return result

    # The meat of the function
    # Log the timestamps for debugging and logistics
    logging.INFO("Navbar Render Begun at " + datetime.now())
    query = NavigationItem.objects.filter(top_level=True).order_by('position')
    result = generate_navigation(query)
    logging.INFO("Navbar Rendered at " + datetime.now())
    if Cache.objects.filter(key="nav").count() > 0:
        cache = Cache.objects.get(key="nav")
        cache.data = result  # WTF HOW DID I FORGET THIS???
    else:
        cache = Cache(key="nav", data=result)
    cache.save()
    logging.INFO("Navbar Saved at: " + datetime.now())

    return result

完整错误:

  Traceback (most recent call last):
File "manage.py", line 22, in <module>
  execute_from_command_line(sys.argv)
File "C:\Program Files\Python 3.5\lib\site-packages\django\core\management\__init__.py", line 367, in execute_from_command_line
  utility.execute()
File "C:\Program Files\Python 3.5\lib\site-packages\django\core\management\__init__.py", line 341, in execute
  django.setup()
File "C:\Program Files\Python 3.5\lib\site-packages\django\__init__.py", line 27, in setup
  apps.populate(settings.INSTALLED_APPS)
File "C:\Program Files\Python 3.5\lib\site-packages\django\apps\registry.py", line 108, in populate
  app_config.import_models(all_models)
File "C:\Program Files\Python 3.5\lib\site-packages\django\apps\config.py", line 199, in import_models
  self.models_module = import_module(models_module_name)
File "C:\Program Files\Python 3.5\lib\importlib\__init__.py", line 126, in import_module
  return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 662, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "C:\Users\User\project\navbar\models.py", line 2, in <module>
  from navbar.generator import update_navigation
File "C:\Users\User\project\navbar\generator.py", line 1, in <module>
  from navbar.models import Cache, NavigationItem
ImportError: cannot import name 'Cache'

1 个答案:

答案 0 :(得分:8)

这是正常的,因为你正在进行循环导入(从generator.py导入models.py,反之亦然)

尝试在模型中使用方法导入然后应该修复:

class NavigationItem(models.Model):
    ...

    def save(self, *args, **kwargs):
        # Method level import to avoid circular imports
        from .navigation import update_navigation
        super(NavigationItem, self).save(*args, **kwargs)
        logging.INFO("Saved Navbar at " + datetime.now())
        update_navigation()