1. 程式人生 > >Python Django建立web專案例項中遇到的問題以及解決方法

Python Django建立web專案例項中遇到的問題以及解決方法

目錄

前言

問題一: 'Specifying a namespace in include() without providing an app_name '

1. 出現背景:    

2. 原因:

3. 解決辦法:

問題二: Page not found(404)

1. 出現背景:  

2. 原因:

3. 解決辦法:

問題三: TemplateDoesNotExist at /XXX

1. 出現背景:

2. 原因: 

3. 解決辦法:

問題四: Model class XXX doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

1. 出現背景:

2. 原因: 

3. 解決辦法:



 

前言

《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呼叫正常