Django 之 三大系統


urls.py – 路由系統

基本使用

  • urls.py
# 上方導入模塊
from django.urls import path

urlpatterns = [
    # 基本使用, 路由匹配 index/ , 訪問 views 中的 index 方法 
	path('login/', views.login), 
]

  • views.py
# 設置一個方法, 接收並處理請求
def login(request):
    return render(request, "login.html")
    

別名用法

  • urls.py
# 上方導入模塊
from django.urls import path

urlpatterns = [
    # 基本使用, 路由匹配 index/ , 訪問 views 中的 index 方法 
	path('index/', views.index, name="index"), 

]
  • views.py
# 需要導入 reverse 模塊
from django.urls import reverse

# 如果成功, 會訪問別名爲 index 的頁面
def index(request):
	# if login success
    return redirect(reverse("index")) # 這裏的 index 和 urls 中 name 的字段對應
    

位置傳參

  • urls.py
# 傳參需要使用正則匹配, 後期的 django 需要導入 re_path 模塊
from django.urls import re_path

urlpatterns = [
    # 使用 re_path 模塊, 正則匹配規則
	re_path(r're1/(\d+)/(\d+)/$', views.re_1),
]

  • views.py
# 接收位置參數
def re_1(request,  arg1):
    return HttpResponse(arg1)


關鍵字傳參

  • urls.py
# 傳參需要使用正則匹配, 後期的 django 需要導入 re_path 模塊
from django.urls import re_path

urlpatterns = [
    # 使用 re_path 模塊, 正則匹配規則, ?P<key> 表示關鍵字
    re_path(r're2/(?P<re2_id>\d+)/$', views.re_2),
]

  • views.py
# 關鍵字傳參, 
def re_2(request, re2_id): # re2_id 對應 urls 中 <> 中的字段
    return HttpResponse(re2_id)
    

include 用法

  • projectDir/urls.py
# 需要導入 include 模塊
from django.urls import include

urlpatterns = [
	# include 中寫明哪個目錄下的 urls 文件, 這樣有利於分別管理
	path('stu/', include("stu.urls"))
]

  • stu/urls.py
urlpatterns = [
    # 此時訪問的 url 爲 http://ip:port/stu/stu_add/
    path('stu_add/', views.stu_add),
]


views.py – 視圖系統

FBV 和 CBV

  • views.py
# 需要導入 views 模塊
from django import views

# CBV, Class, 繼承 views.View
class exp1(views.View):
    def get(self, request):
        return HttpResponse("exp1.get")

    def post(self, request):
        return HttpResponse("exp1.post")

# FBV, Function
def exp2(request):
	return HttpResponse("exp2")
	
  • urls.py
# 接收 FBV 和 CBV 時不同
urlpatterns = [
	# 接收 CBV
	path('exp1', views.exp1.as_view())
	
	# 接收 FBV
	path('exp2', views.exp2)
]


給 CBV 加裝飾器

from django.utils.decorators import method_decorator

# 這是個裝飾器
def wrapper(func):
    def inner(*args, **kwargs):
        ret = func(*args, **kwargs)
        return ret
    return inner


class Asset(views.View):
  
    def get(self, request):
        pass

	# 使用 method_decorator裝飾器, 並且將需要使用的裝飾器作爲參數傳給它
	@method_decorator(wrapper)
    def post(self, request):
        pass
      


取多選數據

  • views.py
class AuthorEdit(views.View):

    def get(self, request, id):
        author = models.Author.objects.filter(id=id).first()
        books = models.Book.objects.all()
        return render(request, "author_edit.html", {"author": author, "books": books})

    def post(self, request, id):
        name = request.POST.get("author")
        # getlist 表示取多選數據
        books = request.POST.getlist("books")

        author_obj = models.Author.objects.filter(id=id).first()
        author_obj.name = name
        author_obj.books.set(books)
        author_obj.save()

        return redirect("/author_list/")

  • author_edit.html
{% extends "mom.html" %}

{% block html_title %}
編輯作者
{% endblock %}

{% block html_main %}
    <form action="" method="post">
        {% csrf_token %}
        <p>
            作者:
            <input type="text" name="author" value="{{ author.name }}">
        </p>
        <p>
            書名:
            <select name="books" multiple>
                {% for foo in books %}
                    {% if foo in author.books.all %}
                    	# selected 表示選中
                        <option selected value="{{ foo.id }}">{{ foo.title }}</option>
                    {% else %}
                        <option value="{{ foo.id }}">{{ foo.title }}</option>
                    {% endif %}
                {% endfor %}
            </select>

            {% for i in books %}
                {% if i in author.books.all %}
                	# checked 表示選中
                    <p><input checked type="checkbox" name="books" value="{{ i.id }}">{{ i.title }}</p>
                {% else %}
                    <p><input type="checkbox" name="books" value="{{ i.id }}">{{ i.title }}</p>
                {% endif %}
            {% endfor %}

        </p>
        <p><input type="submit" value="修改"></p>
    </form>
{% endblock %}

上傳文件

  • views.py
class Upload(views.View):
    def get(self, request):
        return render(request, "upload.html")

    def post(self, request):
        # 保存文件
        file_obj = request.FILES.get("code")
        # 拿到文件名
        filename = file_obj.name
        with open(filename, "wb") as f:
            # 往文件句柄中寫入
            for i in file_obj.chunks():  # .chunk()是 django 自帶的方法, 更加標準
                f.write(i)
        return HttpResponse("上傳成功")

  • upload.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
		<!-- 上傳文件的時候一定要寫明 enctype -->
		<form action="/upload/" method="post" enctype="multipart/form-data">
    		<input type="file" name="code">
    		<input type="submit" value="提交">
		</form>
</body>
</html>


直接返回 json 結果

# 需要導入 JsonResponse 模塊
from django.http import JsonResponse

class JsonTest(views.View):
    def get(self, request):
        res = {"code": 0, "data": "alex"}
        res2 = ["alex", "wusir", "mjj"]

        # django 實現序列化, 默認只支持字典, 當 safe 爲 False可以返回其他類型
        return JsonResponse(res2, safe=False)


template – 模板系統

基本語法

# 雙括號是變量相關
{{ name }} # name 爲變量名
{{ obj.key }} # 根據 key, 取字典的值
{{ ojb.index }} # 根據 index, 取列表的元素


顯示默認值

# 有值顯示值, 無值顯示"暫無數據"
{{ data|default:"暫無數據" }}


轉換文件大小

# 假數據
filesize = 1024000 

# 將數字直接轉換成文件大小展示
{{ filesize|filesizeformat }}


格式化時間

# 假數據
date = datetime.datetime.today() 

# 時間格式化成我們想要的樣子
{{ today|date:"Y-m-d H:i:s" }}


展示鏈接

# 假數據
link = "<a href='www.baidu.com>百度</a>"

# 需要添加 safe 才能展示爲超鏈接
{{ link|safe }}

for 循環

判斷是否爲最後一次

# 假數據
data = [1, 2, 3, 4]

{% for i in data %}
	{% if forloop.last %}
		{{ i }}
	{% else %}	
		{{ i }},
	{% endif %}
{% endfor %}

# 結果爲
1,2,3,4

數據爲空顯示默認值

# 假數據
data = ""

{% for i in data %}
	{{ i }}
{% empty %}
	"默認值"	
{% endfor %}

# 結果爲
"默認值"

母版和組件

  • 母版文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! -->
    <title>
        {% block page_title %}
		標題的位置
        {% endblock %}
    </title>

    <link href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
    {% block page_css %}
    單頁面引入 css 文件位置
    {% endblock %}
</head>
<body>
    <div class="row">
        <div>

        </div>
    </div>
    <div class="container">
        <div class="row" style="margin-top: 70px">
            {% block page_main %}
            頁面代碼位置
            {% endblock %}
        </div>
    </div>

    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依賴 jQuery,所以必須放在前邊) -->
    <script src="/static/jQuery/jQuery3.4.1.min.js"></script>
    <!-- 加載 Bootstrap 的所有 JavaScript 插件。你也可以根據需要只加載單個插件。 -->
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>

    {% block page_js %}
    單頁面引入 js 文件位置
    {% endblock %}
</body>
</html>

  • 組件, 文件名爲 zujian.html
<p> 這是一個組件文件 </p>

  • 引入母版和組件
# 引入母版文件
{% extends "base.html" %}

# 填充非公用代碼
{% block page_title %}
主頁
{% endblock %}

{% block page_main %}

<p><a href="/index/">主頁</a></p>
# 引入組件, 導入文件名即可
{% include "zujian.html" %}

{% endblock %}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章