---
# System prepended metadata

title: 技術｜Django 筆記
tags: [技術]

---

# Django 筆記

## 1.同一個視圖函數來處理不同的路由
- 當請求匹配到 'post/<int:post_id>/' 路由時，Django 將提取 post_id 作為參數，並將其傳遞給 post_view 函數進行處理。同樣地，當請求匹配到 'post/latest/' 路由時，post_view 函數將被調用，不過這次沒有額外的參數。
    ```python=
    # urls.py
    from django.urls import path
    from . import views

    urlpatterns = [
        path('post/<int:post_id>/', views.post_view, name='post_detail'),
        path('post/latest/', views.post_view, name='latest_post'),
    ]
    ```
    ```python=
    # view.py
    def post_view(request, post_id=None):
        if post_id is not None:
            # 根據 post_id 做相應處理
            post = Post.objects.get(id=post_id)
            return render(request, 'post_detail.html', {'post': post})
        else:
            # 處理最新文章的邏輯
            latest_post = Post.objects.latest('publish_date')
            return render(request, 'latest_post.html', {'latest_post': latest_post})

    ```
## 2.視圖函數應該回傳什麼
- 字符串響應：你可以直接返回一個字符串作為響應。Django 將自動將其轉換為 HTTP 響應。
- 渲染模板：你可以使用模板引擎來渲染模板並返回響應。
- 重定向：你可以將用戶重定向到另一個 URL。
- JSON 響應：你可以返回 JSON 格式的數據。
    ```python=
    from django.http import HttpResponse
    from django.shortcuts import render
    from django.shortcuts import redirect
    from django.http import JsonResponse

    def my_view(request):
        return HttpResponse('Hello, World!')

    def my_view(request):
        context = {'name': 'John'}
        return render(request, 'my_template.html', context)

    def my_view(request):
        return redirect('/another-url/')

    def my_view(request):
        data = {'name': 'John', 'age': 30}
        return JsonResponse(data)
    ```
- 比較 `render` 和 `render_to_response`
    - `render_to_response` 函數需要顯式指定模板名稱，並可選地提供上下文和其他參數。它更靈活，但使用起來相對複雜。
    - Django 鼓勵使用 render 函數作為更簡單和一致的模板渲染方法，`render_to_response`  在 Django 3.0 版本中已被標記為過時。

## 3. 視圖函數搭配 context
- context 是一個字典，用於在視圖函數和模板之間傳遞數據
    - 在模板中，你可以使用 {{ username }} 來訪問 'username' 的值
    - 可以用 context.get() 得到數據
    ```python=
    from django.shortcuts import render

    def my_view(request):
        context = {
            'username': 'John',
            'age': 30,
        }
        occupation = context.get('occupation', 'N/A') # 如果 'occupation' 在上下文中不存在，則會顯示默認值 'N/A'。
        return render(request, 'my_template.html', context)
    ```

## 4. 模板引擎的一個模板使用 include 引入其他模板
- include指令是Django模板引擎提供的功能
    ```django=
    --- main.html
    <!DOCTYPE html>
    <html>
    <head>
      <title>我的網站</title>
    </head>
    <body>
      {% include 'header.html' %}

      <main>
        {% include 'content.html' %}
      </main>

      <footer>
        <!-- 頁面的頁尾內容 -->
      </footer>
    </body>
    </html>
    
    
    --- header.html
    <header>
      <h1>這是頁面的標題</h1>
    </header>
    content.html：


    --- content.html
    <section>
      <h2>這是內容區塊</h2>
    </section>
    ```