Python Django建立web專案例項中遇到的問題以及解決方法
目錄
問題一: 'Specifying a namespace in include() without providing an app_name '
問題三: TemplateDoesNotExist at /XXX
前言
《Python程式設計從入門到實踐》書中,第18章介紹了使用Django模組建立web專案的實踐方法,但在實際操作過程中,發現因為版本更新等問題,會出現一些問題。經過搜尋解決問題、檢視文件等方法,將這些問題成功修復,專案正常執行。在此做個記錄,幫助其他同學快速改進
我使用的python版本3.6.3, Django版本2.1.2,並且沒有建立虛擬環境venv
根據書中指導,在大專案中建立了自己的子專案app: learning_logs
python manage.py startapp learning_logs
在其中建立models、views、templates等操作,專案結構如下:
問題一: 'Specifying a namespace in include() without providing an app_name '
1. 出現背景:
urls.py配置添加了到learning_logs的對映,將http://localhost:8000/對映轉入learning_logs的子app,根據書中編寫如下:
"""urls.py中配置""" urlpatterns = [ path('admin/', admin.site.urls), # 新新增的對映 path(r'^$', include('learning_logs.urls', namespace='learning_logs')), ]
啟動程式後,後臺報錯:
2. 原因:
在include方法裡面指定namespace引數,卻不提供app_name,是不允許的。 所以報錯
3. 解決辦法:
修改 urls.py的配置
"""urls.py中配置(修改後)"""
urlpatterns = [
path('admin/', admin.site.urls),
# 新新增的對映(修改後,將namespace的引數值用元組也傳入include第一個引數中)
path(r'^$', include(('learning_logs.urls','learning_logs'), namespace='learning_logs')),
]
可以看到將'learning_logs'也傳入include()的第一個引數中,之後啟動正常:
問題二: Page not found(404) The current path, /XXX
, didn't match any of these.
1. 出現背景:
"""urls.py中配置(修改後)"""
urlpatterns = [
# 新新增的對映(修改後,將namespace的引數值用元組也傳入include第一個引數中)
path(r'^$', include(('learning_logs.urls','learning_logs'), namespace='learning_logs')),
]
urls.py配置如上所示,啟動伺服器後,使用瀏覽器訪問: http://localhost:8000/ 出現Page not found(404)頁面,如下:
(我這裡截圖有詳細資訊是因為settings.py中開了DEBUG = True,如果不開可能沒有詳細資訊,但通過看瀏覽器後臺請求也可以發現錯誤碼404
)
2. 原因:
可以看到,伺服器的兩個uri對映,一個是admin,另一個是^$,正是我們在urls.py中的配置。但不同的是,我們原先的配置為r"^$",為正則表示式,是希望攔截一個空字串,但系統沒有生效。
根據查詢,書中的這種正則表示式配置,在Django版本升級之後變的不能直接用了。解決方法有兩種:
- 不使用正則表示式,直接使用""進行匹配
- 如果必須使用正則表示式,則需要用re_path() 替換 path()
3. 解決辦法:
1) 不使用正則表示式, 修改urls.py 如下
urlpatterns = [
# 新新增的對映,不用正則表示式
path("", include(('learning_logs.urls','learning_logs'), namespace='learning_logs')),
]
2) 必須使用正則表示式的場景,則使用re_path() 替換 path(), 修改urls.py 如下
from django.urls import re_path
urlpatterns = [
# 新新增的對映,使用正則表示式
re_path('^$', include(('learning_logs.urls','learning_logs'), namespace='learning_logs')),
]
兩種方法都能解決URL對映問題
問題三: TemplateDoesNotExist at /XXX
1. 出現背景:
當新建立learning_logs的子app後,將http://localhost:8000/ uri對映在learning_logs時,編寫learning_logs/urls.py,對映在learning_logs/templates/index.html中,如下:
"""learning_logs/urls.py"""
urlpatterns = [
path('', views.index, name='index'),
]
但在實際使用瀏覽器呼叫:http://localhost:8000/後,後臺會報:TemplateDoesNotExist,如下
2. 原因:
learning_logs/templates這個資料夾,並不在系統檢索的模板資料夾內,所以沒有檢索到對應的index.html檔案,報錯
3. 解決辦法:
需要在settings.py中新增配置,以使learning_logs/templates進入檢索模板資料夾,共有兩種方法:
1) 使learning_logs這個app在web專案中生效(app在web專案中生效後,其下面的templates資料夾自動會進入被檢索的templates資料夾內):
在settings.py 的 INSTALLED_APPS配置中,新增一行:'learning_logs' , 如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.sites', # 新加一行
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 我的應用程式
'learning_logs',
]
2) 直接將learning_logs/templates資料夾新增入模板檢索資料夾內
在settings.py的TEMPLATES中的'DIRS'中新增:“learning_logs/templates”(舊Django版本中,是在TEMPLATES_DIRS中新增配置),如下:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 新增指定的模板資料夾地址
'DIRS': [os.path.join(BASE_DIR, "learning_logs\\templates").replace('\\','/')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
這兩種都能生效
問題四: Model class XXX doesn't declare an explicit
app_label and isn't in an application in INSTALLED_APPS.
1. 出現背景:
在子app:learning_logs的models中編寫了資料庫DAO對映類Topic,如下:
class Topic(models.Model):
"""使用者學習的主題"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""返回模型的字串表示"""
return self.text
當想要在自己的html中呼叫此Topic,拿到所有資料前端展示時:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li> {{ topic }}</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
在啟動專案時,就會報錯。截圖如下:
2. 原因:
報錯日誌中,其實已有明確的解釋,如本例,提示到learning_logs.models.Topic 類沒有宣告為一個顯式的app_label,並且沒有在INSTALLED_APPS中註冊為一個application應用
3. 解決辦法:
在settings.py中的INSTALLED_APPS中,註冊 learning_logs,如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.sites', # 新加一行
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 我的應用程式
'learning_logs',
]
再啟動程式,可以看到正常執行,url呼叫正常