Django中包、模块导入问题
刚开始接触Django框架,在学习过程中遇到一个比较奇怪的报错。
在此记录一下,并提供一个解决过程,其中很多涉及Python模块和包的导入问题还有进行分析
希望以后能够仔细分析以后再进行填坑
通过查阅Python的资料发现,导入模块和包的方式一般有以下方式:
import module_name # 直接导入模块
from package import module_name # 从包中环境变量中的路径下查找指定模块进行导入
from . import module_name # 从同级目录下
from .. import module_name # 从上级目录下进行导入
遇到问题的Python模块文件如下:
models.py 文件
# models.py
from django.db import models
# Create your models here.
class BookInfo(models.Model):
title = models.CharField(max_length=30)
pub_date = models.DateField()
class HeroInfo(models.Model):
name = models.CharField(max_length=10)
gender = models.BooleanField(default=True)
content = models.CharField(max_length=100)
book = models.ForeignKey(BookInfo, on_delete=models.CASCADE)
admin.py 文件
# admin.py
from django.contrib import admin
from models import BookInfo, HeroInfo
# Register your models here.
admin.site.register([BookInfo, HeroInfo])
按以上方式对模型类进行注册的时候,启动服务器会遇到如下报错,
from models import BookInfo, HeroInfo
ModuleNotFoundError: No module named 'models'
建立的项目APP目录树如下:
.
└── BookProject
├── BookApp
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-37.pyc
│ │ ├── admin.cpython-37.pyc
│ │ └── models.cpython-37.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── BookProject
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-37.pyc
│ │ ├── settings.cpython-37.pyc
│ │ ├── urls.cpython-37.pyc
│ │ └── wsgi.cpython-37.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
└── manage.py
在Django项目APP目录中,admin和models模块是兄弟模块,且在同一级目录中,但是不能直接通过以下几种方式进行导入,且无法通过绝对路径进行导入
from package import module
from BookProject.BookApp.models import BookInfo
from models import BooInfo
最终解决方式如下:
from .models import BookInfo
必须通过相对路径的方式导入,经过验证,在其他的项目中暂时未发现必须使用相对路径进行导入的问题,同时在这个Django项目中,APP目录中的__init__.py为空白,并未进行设置
在其他项目中进行验证,发现采用相对路径导入会出现模块以下报错
ModuleNotFoundError: No module named '__main__.module_name'; '__main__' is not a package
个人猜测,并未经过验证的一种可能性是未将模块路径保存至系统变量,所以会出现以上报错,查找资料得到的解释是Python中的相对路径不是真实的,使用相对路径时,Python是没有导入路径的上级目录和本级目录,所以无法采用相对路径
如Django项目中admin中导入models,采用相对路径是无法识别到BookApp(本级目录)和BookProject(上级目录),故无法识别到其他的模块[1]
本文中的Django项目不知道为什么必须采用相对路径导入models模块, [1] 中的两个目录只是用Django项目目录进行举例,用来说明其他的项目情况