Django 教程之media和static靜態檔案

_Johnny_發表於2020-12-09

區別

Django有兩種靜態檔案:

  • static 稱為靜態資料夾,是不變的,形成網站的核心部件,如 CSS檔案,JS檔案,背景圖片等;可為Templates模板提供支援
  • media 稱為媒體資料夾,是變動的,由使用者定義的檔案,如 使用者頭像, 使用者上傳的圖片或視訊等;可為富文字編輯器mdeditor提供支援

配置說明

我要做的是個人部落格,不提供其他人註冊登入功能,故media只是為了存放文章的封面、圖片等資訊。

故在目錄方面,我的設定如下:

  1. static目錄與Templates目錄放在一起,由“主題目錄接管”
  2. 主題目錄:與manage.py同級目錄下建立templates目錄,目錄下建立主題資料夾,如default,裡面建立templates和static靜態資料夾
  3. 如果想更換主題,只需建立新主題資料夾,變動templates和static即可
  4. media目錄放在根目錄,畢竟我的“主題”無論怎麼換,部落格文章內容不會換,涉及的本地圖片不會變動

配置static目錄

https://docs.djangoproject.com/en/1.11/howto/static-files/

Django的靜態檔案處理一般分debug模式和非debug模式

  • debug模式的情況下允許訪問靜態資源,無需STATIC_ROOT
  • 非debug模式也就是生產模式,在伺服器執行時, 靜態資源需要使用nginx或者apache之類的工具維護

簡單說下:

  • STATIC_URL - 可以理解為通過url訪問static檔案的路徑,

    如 專案路徑是,{{projectName}}/static/common_static/test.css

    ​ 則訪問url是: http://IP/static/common_static/test.css

  • STATIC_ROOT - 可以理解為你打算在伺服器上儲存static檔案的路徑(通過 python manage.py collectstatic命令),collectstatic命令後將複製靜態檔案到STATIC_ROOT指定的目錄中, 部署django專案的時候需要

  • STATICFILES_DIRS - 可以理解為配置Django尋找靜態檔案時首先去STATICFILES_DIRS裡面尋找, 其次再到各個app的static資料夾裡面找,Django查詢靜態檔案是惰性查詢,查詢到第一個,就停止查詢了

    django放置靜態檔案有兩種方式,一是在每個app裡新建一個static目錄,將靜態檔案放置其中;另一種是對公共檔案的處理,如jQuery bootstrap等,這時就需要配置 STATICFILES_DIRS。

配置方法:

  1. 確定主題目錄`/templates/default/,建立static資料夾

  2. debug模式在settings中進行設定

    # 對外提供WEB訪問時的URL地址
    STATIC_URL = '/static/'
    # 開發階段放置專案自己的靜態檔案,不能包含STATIC_ROOT路徑
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'templates', THEME, 'static'),
    ]
    
  3. 非debug模式在settings中進行設定,需要修改

    在`settings.py`同級的`urls.py`內還需要把`STATIC_URL`和django的url連線起來
    from django.contrib.staticfiles.urls import staticfiles_urlpatterns
    urlpatterns += staticfiles_urlpatterns()
    
    STATIC_URL = '/static/'
    
    # 執行collectstatic命令後會將專案中的靜態檔案(包括STATICFILES_DIRS、自帶admin的靜態檔案)收集到該目錄下面來(所以不應該在該目錄下面放置自己的一些靜態檔案,因為會覆蓋掉)
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'collect_static'),
    )
    
  4. 模板中使用靜態檔案,load static

    {%load static%}和{%load staticfiles%}:哪個是首選?

    https://stackoverflow.com/questions/34422971/load-static-and-load-staticfiles-which-is-preferred

    {% load static %}
    
    <img src="{% static "my_app/example.jpg" %}" alt="My image"/>
    
  5. 模板中使用靜態檔案,無需load static,配置全域性使用load static

    TEMPLATES加入'builtins': ['django.templatetags.static']

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates', THEME, 'templates')],
            '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',
                ],
            'builtins': ['django.templatetags.static']
            },
        },
    ]
    

    使用,無需{% load static %},html中直接使用

    <script src="{% static 'js_dist/jquery.min.js' %}"></script>
    

不能確實是不是需要引入這個需要修改

# from django.templatetags import static
        ``# 在模板中設定 static 後,以後在頁面中使用
        ``# static 就不需要每個頁面都使用 {% load static %}加

配置media目錄

簡單說下:

  • MEDIA_ROOT - 設定使用者上傳檔案的實際儲存目錄,該資料夾自動建立

  • MEDIA_URL - 代表使用者通過URL來訪問這個本地地址的URL

    如 本機MEDIA_URL 為”/media/”則訪問url是: http://IP/media/***

配置方法:

  1. settings.py進行設定

    MEDIA_URL='/media/'
    MEDIA_ROOT=os.path.join(BASE_DIR,"media")
    
  2. urls.py路由設定

    from django.conf import settings         # 匯入專案資料夾中settings.py模組
                                             # 或者 from . import settings
    from django.views.static import serve    # 匯入相關靜態檔案處理的views控制包
    
    urlpatterns = [
        url('media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}),
    ]
    
  3. models.py模板設定

    FileFieldImageField欄位適用於儲存檔案/圖片,出於效能考慮,檔案並不直接儲存到資料庫,而是儲存在檔案系統裡,因此該欄位只是記錄一個路徑而已。

    img_link = models.ImageField(upload_to='images/%Y-%m', max_length=255,
                                     help_text='提示:不新增封面可以不選擇圖片,預設沒有圖片',
                                     blank=True, null=True, verbose_name='文章封面')
                                     
    upload_to相當於上傳到/media/images目錄下,格式為year-month,如2019-10
    
    
    avatar = models.FileField(verbose_name='頭像', upload_to='upload/avatar/')
    
    upload_to相當於上傳到/media/upload/avatar/目錄下
    
  4. 模板HTML中引用路徑

    • 方式一

      <img src="/media/{{ article.img_link }}">
      
    • 方式二

      <img src="{{ article.img_link.url }}">
      

當前不知道以下設定的用途,用到再說:

  1. TEMPLATES設定中的context_processor選項中加入:‘django.template.context_processors.media’, 據說是為了在html中引用{{ media_url }},會把media_url 註冊到HTML

  2. 將media也加入靜態檔案目錄列表中,STATICFILES_DIRS = [ os.path.join(BASE_DIR, ‘static’), os.path.join(BASE_DIR, ‘media’), ]

  3. mdeditor貌似用到了。

在檔案最後加上: +static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

即 urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

相關文章