You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django-Tables2-Column-Shifter获取表类时触发frozen importlib错误

问题描述

我在Django项目的app1中已成功使用Django-Tables2-Column-Shifter库,在另一个使用独立模型的应用app2中复用相同逻辑调用该库时抛出异常,报错信息如下:

File "/home/datavizapp/.virtualenvs/venv/lib/python3.9/site-packages/django/utils/module_loading.py", line 17, in import_string
    module = import_module(module_path)
  File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 984, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'mysite'

其余代码逻辑均可正常运行,仅替换get_table_class相关逻辑时触发报错:

  • 正常运行代码:
tabledata_table = get_table_1_class(
    self.table_class_version
)(tabledata_queryset)
  • 触发报错代码:
tabledata_table = get_table_2_class(
    self.table_class_version
)(tabledata_queryset)

相关代码

app2/views.py

from project_name.app1.models import Table1
from project_name.app2.models import Table2

from project_name.app2.tables import get_table_1_class
from project_name.app2.tables import get_table_2_class
#from project_name.app1.tables import get_table_1_class # 取消注释后可正常运行(原代码位于app1中)

from django_tables2_column_shifter.tables import (
    ColumnShiftTableBootstrap4
)

from django.contrib.auth import get_user_model
User = get_user_model()
from django.views.generic import TemplateView
from django_tables2.config import RequestConfig


class Base(object):

    container_css = "span10 offset1"
    template_name = "cryptoscreener/shifter-template.html"
    table_class_version = ColumnShiftTableBootstrap4

    def get_context_data(self, **kwargs):

        context = super(Base, self).get_context_data(**kwargs)

        # 构建表
        tabledata_queryset = Table1.objects.all()
        #tabledata_queryset = Table2.objects.all() # 该行代码可正常运行

        # 下方为报错触发位置,当前代码可正常运行,替换为get_table_2_class即触发报错
        tabledata_table = get_table_1_class(
            self.table_class_version
        )(tabledata_queryset)

        # 开启排序与分页
        RequestConfig(self.request, paginate={'per_page': 20}).configure(tabledata_table)

        context['container_css'] = self.container_css
        context['tabledata_table'] = tabledata_table
        context['tabledata_queryset'] = tabledata_queryset

class Bootstrap5(Base, TemplateView):
    container_css = "col-xs-10 col-xs-offset-1"
    template_name = "cryptoscreener/shifter-template.html"
    table_class_version = ColumnShiftTableBootstrap4

app2/tables.py

from project_name.app1.models import Table1

def get_table_1_class(TableClass):

    class Table1Class(TableClass):

        class Meta:
            model = Table1

    return Table2Class

# 从app2的views.py调用get_table_2_class时出现报错
from project_name.app2.models import Table2

def get_table_2_class(TableClass):

    class Table2Class(TableClass):

        class Meta:
            model = Table2

    return Table2Class

模板文件 shifter-template.html

{% load static %}
{% load django_tables2 %}
{% load render_table from django_tables2 %}

<!DOCTYPE html>
{% load static %}
<html lang="{{ LANGUAGE_CODE|default:"en" }}">
    <head>
        <title>Testproject</title>
        <meta charset="utf-8">
        <meta name="description" content="Testproject for django-tables2-column-shifter">
        <meta name="author" content="Grzegorz Tężycki">

        {#  bootstrap样式 #}
        {% block bootstrap_css %}
            <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        {% endblock %}

        {% block extra_head %}{% endblock extra_head %}

        <style>
            body {
                width : 90%;
                margin: 0 auto;
            }
        </style>
    </head>

    <body>

        {% render_table tabledata_table %}

        {% block body_ekstra %}

            {# bootstrap脚本 #}
            {% block bootstrap_js %}
            {% endblock %}

            {# !! --> column_shifter依赖JS #}
            <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
            <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
            <script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.3/dist/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
            <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
            <script type="text/javascript" src="{% static 'django_tables2_column_shifter/js/django_tables2_column_shifter.min.js' %}"></script>

        {% endblock body_ekstra %}
    </body>
</html>

settings.py 中 INSTALLED_APPS 配置

# APPS
# ------------------------------------------------------------------------------
DJANGO_APPS = [
    "rest_framework",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.sites",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # "django.contrib.humanize", # 实用模板标签
    "django.contrib.admin",
    "django.forms",
]
THIRD_PARTY_APPS = [
    "crispy_forms",
    "allauth",
    "allauth.account",
    "allauth.socialaccount",
    "allauth.socialaccount.providers.google",
    "django_tables2",
    "django_tables2_column_shifter",
    "bootstrap4",
    "django_filters",
    "stripe", # 支付用stripe
    "annoying", # django-annoying
    "tailwind", # tailwind css
    "widget_tweaks",
]

LOCAL_APPS = [
    "project_name.users.apps.UsersConfig",
    # 自定义应用在此处添加
    "project_name.app1.apps.App1Config",
    "project_name.app2.apps.App2Config",
    "theme", # tailwind css 相关
]
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

项目结构

Django项目结构


排查思路与修复方案

首先修正代码里的明确笔误:app2/tables.py中get_table_1_class函数内定义的类为Table1Class,但返回值写的是Table2Class,属于低级拼写错误。

核心报错ModuleNotFoundError: No module named 'mysite'由两个原因共同导致:

  1. 函数内部动态定义的表类默认__module__属性解析异常,django-tables2-column-shifter内部做动态类导入时,错误拼接了不存在的mysite前缀路径
  2. 项目中残留旧的mysite项目名配置引用,路径解析时命中了无效值

按以下步骤修复即可:

  1. 重写app2/tables.py,修正返回值笔误,同时给动态生成的表类显式指定正确的__module__属性,避免第三方库做路径解析时出错:
from project_name.app1.models import Table1
from project_name.app2.models import Table2

def get_table_1_class(TableClass):
    class Table1Class(TableClass):
        class Meta:
            model = Table1
    # 显式绑定类所属模块路径
    Table1Class.__module__ = "project_name.app2.tables"
    return Table1Class

def get_table_2_class(TableClass):
    class Table2Class(TableClass):
        class Meta:
            model = Table2
    Table2Class.__module__ = "project_name.app2.tables"
    return Table2Class
  1. 全局搜索项目代码,检查manage.py、wsgi.py、asgi.py中的DJANGO_SETTINGS_MODULE配置,确认指向project_name.settings,清理所有残留的mysite字符串引用
  2. 清理项目缓存与编译文件后重启服务:
find . -name "*.pyc" -delete
find . -name "__pycache__" -type d -exec rm -rf {} +

内容的提问来源于stack exchange,提问作者Billy Haskell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:01:14