DJango 框架学习入门教程(三) —— DJango 框架使用常见错误
2024年02月29日 16:03:22 Django ⁄ 共 8093字 暂无评论 ⁄ 被围观 182次

错误一:TypeError: ForeignKey.__init__() missing 1 required positional argument: 'on_delete'

在使用 DJango 框架生成迁移文件的命令(python manage.py makemigrations
 应用名)时,可以看到出现如下错误:

(ll_env) D:\workspace\workspace-mengll\learning-log>python manage.py makemigrations learning_logs
Traceback (most recent call last):
  File "D:\workspace\workspace-mengll\learning-log\manage.py", line 22, in <module>
    main()
  File "D:\workspace\workspace-mengll\learning-log\manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\core\management\__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\core\management\__init__.py", line 416, in execute
    django.setup()
  File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\apps\registry.py", line 116, in populate
    app_config.import_models()
  File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\apps\config.py", line 269, in import_models
    self.models_module = import_module(models_module_name)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python\Python312\Lib\importlib\__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 994, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "D:\workspace\workspace-mengll\learning-log\learning_logs\models.py", line 15, in <module>
    class Entry(models.Model):
  File "D:\workspace\workspace-mengll\learning-log\learning_logs\models.py", line 17, in Entry
    topic = models.ForeignKey(Topic)
            ^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: ForeignKey.__init__() missing 1 required positional argument: 'on_delete'

(ll_env) D:\workspace\workspace-mengll\learning-log>

错误原因是在 DJango 2.0 后,定义外键和一对一关系的时候需要手动加 on_delete 选项,此参数为了避免两个表里的数据不一致问题,不然会报错,而在老版本这个参数(models.CASCADE)是默认值。

所以在模型配置外键时,使用新版本的 DJango 时需要明确指定该配置才行,默认是不添加该参数的。修改代码如下:

class Entry(models.Model):
    """学到的有关某个主题的具体知识"""
    topic = models.ForeignKey(Topic)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

修改为:

class Entry(models.Model):
    """学到的有关某个主题的具体知识"""
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

再执行生成迁移文件的命令时,可以看到错误已解决。 ​

错误二:ModuleNotFoundError: No module named 'learning_logs.urls'

如果自定义的 url 映射关系配置后,访问改页面时后台报错如下:

D:\workspace\workspace-mengll\learning-log\learning_log\urls.py changed, reloading.
Watching for file changes with StatReloader
Performing system checks…

Exception in thread django-main-thread:
Traceback (most recent call last):
File "D:\Python\Python312\Lib\threading.py", line 1073, in bootstrap_inner self.run() File "D:\Python\Python312\Lib\threading.py", line 1010, in run self._target(*self._args, *self._kwargs) File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\utils\autoreload.py", line 64, in wrapper fn(args, **kwargs)
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\core\management\commands\runserver.py", line 133, in inner_run
self.check(display_num_errors=True)
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\core\management\base.py", line 486, in check
all_issues = checks.run_checks(
^^^^^^^^^^^^^^^^^^
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
new_errors = check(app_configs=app_configs, databases=databases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\core\checks\urls.py", line 42, in check_url_namespaces_unique
all_namespaces = _load_all_namespaces(resolver)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\core\checks\urls.py", line 61, in _load_all_namespaces
url_patterns = getattr(resolver, "url_patterns", [])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\utils\functional.py", line 47, in get
res = instance.dict[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\urls\resolvers.py", line 738, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
^^^^^^^^^^^^^^^^^^^
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\utils\functional.py", line 47, in get
res = instance.dict[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\urls\resolvers.py", line 731, in urlconf_module
return import_module(self.urlconf_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Python\Python312\Lib\importlib__init_
.py", line 90, in import_module
return bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1387, in _gcd_import File "", line 1360, in _find_and_load File "", line 1331, in _find_and_load_unlocked File "", line 935, in _load_unlocked File "", line 994, in exec_module File "", line 488, in _call_with_frames_removed File "D:\workspace\workspace-mengll\learning-log\learning_log\urls.py", line 22, in path('', include('learning_logs.urls')), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\workspace\workspace-mengll\learning-log\ll_env\Lib\site-packages\django\urls\conf.py", line 39, in include urlconf_module = import_module(urlconf_module) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Python\Python312\Lib\importlib__init_.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "", line 1387, in _gcd_import
File "", line 1360, in _find_and_load
File "", line 1324, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'learning_logs.urls'

(ll_env) D:\workspace\workspace-mengll\learning-log>

一般是因为配置 URL 后没有重启服务导致的,可以尝试停用服务后,再重新通过 runserver 启动服务访问即可。

错误三:Method Not Allowed (GET): /user/logout/

​在使用 DJango 框架使用框架默认的【登出】视图时,发现报错如下:

Method Not Allowed (GET): /user/logout/
Method Not Allowed: /user/logout/

退出部分的代码原先如下(登出部分见第6行):

<p>
    <a href="{% url 'learning_logs:index' %}">首页</a>
    <a href="{% url 'learning_logs:topics' %}">主题</a>
    {% if user.is_authenticated %}
        你好,{{ user.username }},欢迎您登录^^
        <a href="{% url 'users:logout' %}">登出</a>
    {% else %}
        <a href="{% url 'users:login' %}">登录</a>
    {% endif %}
</p>

{% block content %}{% endblock content %}

原因是 DJango 版本从 5 之后,需要通过 POST 请求来完成登出操作,POST请求可以防止 cross-site 请求伪造 CSRF。因此,需要在登出模板中使用 mini-form 实现请求。

代码修改为如下:

<p>
    <a href="{% url 'learning_logs:index' %}">首页</a>
    <a href="{% url 'learning_logs:topics' %}">主题</a>
    {% if user.is_authenticated %}
        你好,{{ user.username }},欢迎您登录^^
        <form method="post" action="{% url 'users:logout' %}">
            {% csrf_token %}
            <button type="submit">登出</button>
        </form>
    {% else %}
        <a href="{% url 'users:login' %}">登录</a>
    {% endif %}
</p>

{% block content %}{% endblock content %}

修改后【登出】操作即可正常注销登录信息并跳转到登出提示页面。

​​错误4:CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.

​在使用 DJango 框架修改调试方式 DEBUG = False 时,发现项目运行报错如下:

D:\workspace\workspace-mengll\learning-log\learning_log\settings.py changed, reloading.
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
March 02, 2024 - 16:48:57
Django version 5.0.2, using settings 'learning_log.settings'
Starting development server at http://127.0.0.1:8001/
Quit the server with CTRL-BREAK.

D:\workspace\workspace-mengll\learning-log\learning_log\settings.py changed, reloading.
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.

该错误是由 DJango 框架中的 settings.py 配置文件中 DEBUG 设置为 False 时,但因为未设置ALLOWED_HOSTS 的值而触发的错误。所以在 DEBUG 配置下修改 ALLOWED_HOSTS 配置的值即可解决问题。修改后配置代码如下:

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ['localhost']

以上值可以为域名或者 IP 配置,如果为多个值,中间中逗号分隔。如果想配置所有主机或 IP 可访问,则直接配置 ALLOWED_HOSTS = ['*'] 即可。 ​

持续补充中。。。

给我留言

留言无头像?