Django3.2學習筆記


基本常用命令

django-admin

django-admin startproject myproject:創建一個django工程,其中myproject為工程名;
執行上述命令后,會生成如下目錄結構:
myproject/
|------myproject/
|        |------__init__.py
|        |------asgi.py
|        |------settings.py:Django項目配置文件,包括Django模塊應用配置、數據庫配置、模板配置等
|        |------urls.py:Django路由配置
|        |------wsgi.py:與WSGI兼容的Web服務器,為項目提供服務入口
|------manage.py:命令行工具,支持不同的交互運行方式

manage

   說明:manage.py在Django工程目錄下,執行python manage.py命令時,需要先進入工程目錄下
  • python manage.py startapp myapp:創建一個App,其中myapp為App名稱;
執行上述命令后,會在myproject工程目錄下生成如下目錄結構:
myproject/
|------myproject/:目錄結構參見django-admin命令執行后生成的目錄結構
|------manage.py:命令行工具,支持不同的交互運行方式
|------myapp/
|       |------migrations/:用於記錄models中數據結構的變更
|       |------__init__.py
|       |------admin.py:Django自帶的后台管理
|       |------apps.py:用於應用程序配置
|       |------models.py:Django數據模型,定義應用程序數據結構(對應數據庫的相關操作)
|       |------tests.py:Django測試用例相關
|       |------views.py:Django視圖模塊,控制前面頁面顯示的內容
  • python manage.py runserver 127.0.0.1:8000:啟動Django項目,其中127.0.0.1:8000為項目訪問地址及端口
  • python manage.py shell:以終端命令交互的方式啟動Django項目
  • python manage.py test:執行Django測試用例,默認為myproject/myapp/tests.py中的用例
  • python manage.py makemigrations:創建數據模型變更記錄,當數據模型發生變化時,會在myproject/migrations目錄下生成新的形如"0001_initial.py"的文件
  • python manage.py migrate:數據庫遷移,當settings中配置好數據庫后,執行此命令會在數據庫中生成相應的數據表結構

Django架構

MVC & MTV

     0
Model數據模型
數據存取層,定義系統的數據表結構
View視圖模塊
建立用戶與系統的連接頁面,用戶通過request發送請求給Controller,再由Controller分發到指定的路由,經過Model層的數據存取,最終將數據渲染到指定模板文件,並最終呈現到頁面中,由視圖和模板組成
Controller控制模塊
將用戶提交的request分發給View模塊的視圖函數

MTV

     0
Model數據模型
數據存取層,定義系統的數據表結構、數據的存取,通過View模塊聯接
View視圖模塊
業務邏輯層,包括數據模型的存取及調用適當的模板文件的相關邏輯,類型於模型與模板之間的橋梁
Template模板文件
表現層,渲染View層的數據並最終呈現在頁面中

運行流程

說明:由於Django的URLConf自動完成,因此C層被弱化,而T層被單獨抽出
如上圖:
1.用戶通過web瀏覽器向apache服務器發起請求;
2.apache服務器將請求轉發給urls模塊;
3.urls.py至上而下匹配路由配置,匹配成功后,將請求交給視圖模塊views對應的視圖函數處理;
4.視圖函數接收到請求后,將相應的數據請求交給models數據模型;
5.models通過ORM操作數據庫;
6.數據庫操作完成后,將結果返回給models;
7.models將數據結果返回給views視圖函數;
8.views視圖函數將數據結果,並通過指定的模板文件進行渲染;
9.將渲染后的模板文件最終呈現給web瀏覽器

URLconf

   Django通過URLconf模塊來維護網址的解析與views視圖函數的對應關系。

常用方法:(django.urls模塊)

方法
說明
示例
path
指定的地址為確定的地址,不支持正則匹配
path("", views.index)
re_path
指定的地址為不確定的地址,支持正則匹配
re_path("user/(?P\d+)", views.user)
include
 
path("api/", include("allauth.urls"))
reverse
反向生成URL地址,其參數為urls.py中視圖函數對應的name參數
reverse('add')
說明:當re_path中使用的正則表達式如(?P<tid>\d+)時,視圖函數的參數名必須指定為tid

參數說明

  • name:類似於網址的別名,可用於templates、models、views中得到對應的網址,只要這個名字不變,即使網址發生了變化,也能通過這個名字找到正確的網址;

在模板文件中的應用

View Code
View Code
如果網址發生變化但網址別名未發生變化時,通過別名可正確識別變化后的網址,如將新的路由配置修改為如下
View Code
View Code

在視圖函數中的應用

View Code
  • include:路由轉發,用於從根路由出發,將app所屬url請求轉發到子urls.py中,path/re_path中使用;

方法一:只指定urls模塊的字符串

View Code

方法二:同時指定urls(模塊字符串、app_name)、命名空間(當存在多個app時,指定namespace很有必要)

View Code

api/urls.py

View Code

mblog/urls.py

View Code

在template中使用命名空間

View Code

在views中使用命令空間

View Code
注意:namespace與name在模板文件和視圖函數中使用的時候要用冒號分隔,如:"api:host"

Template

配置

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',    # 默認模板引擎
        'DIRS': [],  # 默認為app目錄下的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',
            ],
        },
    },
]
View Code
  • BACKEND:模板引擎,可使用指定的模板引擎,如django.template.backends.jinja2.Jinga2
  • DIRS:模板文件目錄,默認為app目錄下的templates目錄,可指定特定的目錄,常用方式[os.path.join(BASE_DIR, "templates")]

View中的使用

到底使用哪個模板進行渲染,由views.py的視圖函數決定

from django.shortcuts import render

# Create your views here.
def index(request):
    return render(request, "index.html")
View Code
     0
render(request, "index.html", {"username": username})
第一個參數為request,第二個參數為模板文件,第三個為可選參數,接收一個dict類型,在index.html模板文件中需要使用的變量,可通過這個dict參數傳入
說明:第三個參數可利用python的locals()函數替換

使用現有模板框架(此處以bootstrap3為例)

目前接觸到使用bootstrap3的方法有兩種,分別是靜態引用和動態加載

  • 靜態引用

1.安裝bootstrap3

pip install django-bootstrap3

2.在settings.py的INSTALLED_APPS中添加bootstrap3應用

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
    'bootstrap3',
]
View Code

3.在模板文件中引用bootstrap3

<head>
    <meta charset="UTF-8">
    {% load bootstrap3 %}
    {% bootstrap_css %}
    {% bootstrap_javascript %}
    <title>MySite</title>
</head>
View Code
  • 動態加載

      直接通過bootstrap官網,找到CDN並復制到<head></head>標簽中

# 在https://getbootstrap.com/docs/3.4/getting-started/#download網址中,找到BootstrapCDN,
# 將其復制到模板文件的<head></head>標簽中即可
# jQuery框架同樣可以采用此種方式加載

<head>
    <meta charset="UTF-8">
    <title>MySite</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
          integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu"
          crossorigin="anonymous">

    <!-- 可選的 Bootstrap 主題文件(一般不用引入) -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css"
          integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ"
          crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.6.0.js"
            integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous">
    </script>
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"
            integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"
            crossorigin="anonymous">
    </script>
</head>
View Code

支持的語法

{%%}{{}}

{% if exp %}
條件控制語法,語法同python,使用{% endif %}結束條件控制,可配合{% else %}、{% elif %}使用形成分支結構
{% if username %}

登出

{% else %}

登錄

{% endif %}
{% for %}
循環控制語法,語法同python,使用{% endfor %}結束循環控制
 
{% for user in usersusers %}

{{ user.name }}

{% endfor %}
 
可配合{% empty %}顯示特定內容,內部變量:forloop
注意:內部變量forloop只在{% for %}循環內生效,當檢測到{% endfor %}時,forloop即失效不可用
 
{% for user in usersusers %}

{{ user.name }}

{% empty %}

There are no athletes. Only computer programmers.

{% endfor %}
 
forloop.counter:表示循環次數,從1開始開始計數
{% for user in users %}

{{ forloop.counter }}: {{ user }}

{% endfor %}
forloop.counter0:也表示循環次數,但是從0開始計數
{% for user in users %}

{{ forloop.counter0 }}: {{ user }}

{% endfor %}
forloop.revcounter:循環中剩余元素數量,初始值為元素總數,最后一次為1
 
forloop.revcounter0:也是循環剩余元素數量,不過初始值為元素總數-1,最后一次為0
 
forloop.first:Bool類型,第一次循環時返回True,否則返回False
{% for object in objects %}
{% if forloop.first %}
 
{% else %}
 
{% endif %}
{{ object }}
 
{% endfor %}
forloop.last:Bool類型,最后一次循環時返回True,否則返回False
 
{% extends %}
html繼承語法,base.html為html模板文件,類比於Python的基類
{% extends "base.html" %}
{% include %}
html引用語法,將其他html模板文件導入到該html文件中,一般用於網頁的頁眉、頁腳
{% include "header.html" %}
{% include "footer.html" %}
{% load %}
html加載靜態文件/框架
{% load bootstrap3 %}
{% load static %}
{% block %}
用於繼承及實現;在base.html模板文件中定義了{% block %}{% endblock %}之后,所有繼承base.html文件的模板文件都必須實現{% block %}{% endblock %}修飾的內容
base.html
{% block title %}{% endblock %}
index.html
{% extends "base.html" %}
{% block title %}MySite{% endblock %}

使用靜態文件

Django中,使用靜態文件的方式,可以一度程序上提高性能。而Django的靜態文件默認存儲在templates/static中

settings.py中的默認配置

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'
View Code
當然,我們同樣可以通過在settings.py中配置的方式來指定靜態文件的存放位置
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]
View Code
當配置為上述路徑后,靜態文件的目錄路徑則變更為與app同級目錄的static目錄,對於images、css、js則分別創建相應的目錄即可
而在template模板文件中使用靜態文件時,則按照如下方式即可正常引用靜態文件了
<hr>
{% load static %}    # 加載靜態文件
<img src="{% static 'images/logo.png' %}" width=100>
<em>Copyright 2016 a
    <a href="http://www.baidu.com">http://www.baidu.com</a>.
    All rights reserved.
</em>
View Code

常用過濾器

過濾器名稱
用法
示例
capfirst
將字符串首字母大寫
{{ msg | capfirst }},如果msg內容為"django",則html中顯示將變成"Django"
center/ljust/rjust
為字符串加上指定空格后居中、靠左、靠右對齊
{{ msg | center: "15" }}
cut
在字符串中刪除指定的子字符串
{{ msg | cut: " " }},如果msg內容為" How are you",則html中顯示將變成"Howareyou"
date
設置日期的顯示格式
{{ value | date:"D d M Y" }},value為datetime的標准格式。可利用date來設置顯示格式
default
如果沒有值,就使用默認值
{{ msg | default:"沒有信息" }}
first/last
只取出列表數據中的第一個/最后一個元素
{{ values | first }} {{ values | last }},values為列表元素
floatformat
以指定的浮點數格式顯示數據
{{ value | floatformat:3 }},如果value為123.45678,則html中顯示將變成123.457
linebreaks
將文字內容中的換行符號轉換成HTML的

 

{{ msg | linebreaks }}
linebreadsbr
將文字內容中的換行符號轉換成HTML的
{{ msg | linebreaksbr }}
linenumber
為顯示的文字內容加上行號
{{ msg | linenumber}}
lower/upper
將顯示的文字內容轉換成小寫/大寫
{{ msg | lower }} {{ msg | upper }}
random
以隨機數將數據內容顯示出來
{{ values | random }}
safe
標記字符串為安全的,不需要再處理轉義字符
{{ msg | safe }}
striptags
去掉文字內容中的所有HTML標簽
{{ msg | striptags }}
truncatechars
把過長的字符串裁切成指定的長度,並將最后3個字符轉換成...
{{ msg | truncatchars:12 }}
yesno
按照值的內容True/False/None,顯示出有意義的內容
{{ value | yesno:"是,否,可能吧" }}

Models

  Django中,models負責定義數據模型,通過views中的視圖函數與Django Models機制的交互,調用相應的驅動程序接口,實現對數據的存取

配置

在默認配置中,Django以SQLite作為數據庫管理系統,當然也可以使用其他的數據庫管理系統
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
View Code
配置鏈接 mySQL 數據庫
# mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # 數據庫驅動
        'NAME': 'event',  # 數據庫名稱(需要先創建)
        'USER': 'root',  # 數據庫用戶名
        'PASSWORD': '123456',  # 數據庫密碼
        'HOST': '',  # 數據庫主機,留空默認為localhost
        'PORT': '3306',  # 數據庫端口
    }
}
View Code
配置鏈接PostgreSQL 數據庫
# postgresql
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "NAME": "event",
        "USER": "postgres",
        "PASSWORD": "123456",
        "HOST": "localhost",
        "PORT": "5432",
    }
}
View Code

定義模型類

Django提供了完善的模型(model)層來創建和存取數據,它包含你所存儲的數據的必要字段和行為以及類型;
  • 每一個模型都是一個python類,並且繼承自django.db.models.Model類
  • 該模型的每個屬性都表示一個數據庫表的字段
  • 每個模型自動生成一個auto_increment的id字段,並作為主鍵
  • 內部類Meta:用於指定一些特殊屬性,如ordering(排序規則)、unique_together(聯合外鍵)  
示例:
from django.db import models

class Poll(models.Model):

    name = models.CharField(max_length=200, null=False)
    create_at = models.DateField(auto_now_add=True)
    enabled = models.BooleanField(default=False)
    
    class Meta:
        ordering = ("-create_at",)     # 定義結果的排序規則,此處按照創建時間進行排序,"-"表示按照倒序排序

    def __str__(self):
        return self.name

class PollItem(models.Model):

    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)  # 指定PollItem表的外鍵為Poll
    name = models.CharField(max_length=200, null=False)
    image_url = models.CharField(max_length=200, null=True, blank=True)
    vote = models.PositiveIntegerField(default=0)

    def __str__(self):
        return self.name
 
View Code

使用admin后台管理數據模型

Django提供了admin后台管理,對於自定義的數據模型,只需要將數據模型注冊到admin后台管理中就可以了
而注冊admin后台管理也非常簡單,在admin.py中引入數據模型,並調用admin.site.register()方法就可以了
from django.contrib import admin
from mysite.models import Poll


admin.site.register(Poll)
View Code
為了在admin后台管理中能顯示更多的字段,可利用django.contrib.admin.ModelAdmin派生出新的類,並在新的類中對想要的屬性進行調整
from django.contrib import admin
from mysite.models import Poll, PollItem


class PollAdmin(admin.ModelAdmin):

    list_display = ("name", "create_at", "enabled")
    ordering = ("-create_at",)


class PollItemAdmin(admin.ModelAdmin):

    list_display = ("poll", "name", "vote", "image_url")
    ordering = ("poll", )


admin.site.register(Poll, PollAdmin)
admin.site.register(PollItem, PollItemAdmin)
View Code
django.contrib.admin.ModelAdmin中提供了很多定制化的屬性
  • list_display:可迭代對象,其中每個對象對應數據模型中定義的屬性,如:list_display = ("name", "create_at", "enabled")
  • search_fields:搜索器,可迭代對象,同上,如:search_fields = ("name", "poll")
  • ordering:同上,如:ordering = ("-create_at")
  • list_filter:過濾器,可迭代對象,如:list_filter = ("enabled")

常用Model屬性類型

admin.Model提供的常用屬性

AutoField
一個IntegerField類型的自增字段類型
BooleanField
用於存入布爾類型的數據(True/False)
CharField
用於存放字符型的數據,需要指定數據長度,max_length
DateField
日期類型,必須是"YYYY-MM-DD"格式
DateTimeField
日期時間類型,必須是"YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]"
DecimalField
定點數類型,max_digits指定最大值,decimal_places指定小數位數
EmailField
電子郵件類型
FilePathField
文件路徑類型
FloatField
浮點數類型
IntegerField
integer類型,數值范圍從-2147483648g到2147483647
BigIntegerField
用於存放大的integer類型
GenericIPAddressField
存放IP地址類型,支持IPv4和IPv6的字符串格式
NullBooleanField
類似BooleanField類型,但允許為NULL
PositiveIntegerField
integer類型,范圍0~2147483647
TextField
用於存放文本類型的數據
TimeField
時間類型,必須是"HH:MM[:ss[.uuuuuu]]"格式
URLField
用於存放URL地址
BinaryField
存儲原始二進制數據的字段
注意:在models數據模型定義中,屬性中加上verbose_name可定義屬性的中文名

在models.ForeignKey(Poll, on_delete=models.CASCADE)中on_delete參數,支持五種操作:

  • on_delete=models.CASCADE:刪除被引用的對象時,此對象也一並被刪除
# models.py
from django.db import models

class AClass(models.Model):
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

class AListClass(models.Model):
    a_name = models.ForeignKey(AClass, on_delete=models.CASCADE)
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name
        
# admin.py
from django.contrib import admin
from mysite.models import AClass, AListClass

class AListClassAdmin(admin.ModelAdmin):
    list_display = ("name", "a_name")    # AListClass表顯示name字段及外鍵AClass的name字段

admin.site.register(AClass)
admin.site.register(AListClass, AListClassAdmin)
View Code
AClass表添加A1、A2實例,同時AListClass添加a1、a11兩個實例關聯A1,a2、a22兩個實例關聯實例A2
0
當刪除AClass表的A1實例時,會將AListClass表中相關聯的a1、a11實例都刪除
0
確認刪除后,查看AListClass表中,已不存在a1、a11的數據
0
  • on_delete=models.PROTECT:禁止刪除並拋出異常ProtectdError
# models.py
from django.db import models

class BClass(models.Model):
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

class BListClass(models.Model):
    b_name = models.ForeignKey(BClass, on_delete=models.PROTECT)
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

# admin.py
from django.contrib import admin
from mysite.models import BClass, BListClass

class BListClassAdmin(admin.ModelAdmin):
    list_display = ("name", "b_name")

admin.site.register(BClass)
admin.site.register(BListClass, BListClassAdmin)
View Code
BClass表添加B1、B2實例,同時BListClass添加b1、b11兩個實例關聯B1,b2、b22兩個實例關聯實例B2
0
當刪除BClass表的B1實例時,會提示"Cannot delete b class",並提示需要先刪除依賴實例B1的實例才能刪除B1實例
0
刪除BListClass表的b1、b11這兩個依賴B1的實例
0
再次嘗試去刪除BClass表的B1實例,這次就能正常刪除B1實例了
0
  • on_delete=models.SET_NULL:當被引用的對象被刪除后,依賴它的其他對象的該字段都被設置為NULL;設置此操作時,字段必須設置null=True來允許字段值為NULL
# models.py
from django.db import models

class CClass(models.Model):
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

class CListClass(models.Model):
    c_name = models.ForeignKey(CClass, on_delete=models.SET_NULL, null=True)  # 必須指定null=True允許字段值為空
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

# admin.py
from django.contrib import admin
from mysite.models import CClass, CListClass

class CListClassAdmin(admin.ModelAdmin):
    list_display = ("name", "c_name")

admin.site.register(CClass)
admin.site.register(CListClass, CListClassAdmin)
View Code
CClass表創建C1、C2實例,CListClass表添加c1、c11兩個實例關聯實例C1,c2、c22兩個實例關聯實例C2
0
當刪除CClass的C1實例時,與它相關聯的CListClass表的c1、c11實例的c_name字段會被設置為NULL
0
  • on_delete=models.SET_DEFAULT:當被引用的對象被刪除后,依賴它的其他對象的該字段都被設置為默認值;設置此操作時,字段必須設置default參數
# models.py
from django.db import models

class DClass(models.Model):
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

class DListClass(models.Model):
    d_name = models.ForeignKey(DClass, on_delete=models.SET_DEFAULT, default=None, null=True)
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name
        
# admin.py
from django.contrib import admin
from mysite.models import DClass, DListClass

class DListClassAdmin(admin.ModelAdmin):
    list_display = ("name", "d_name")

admin.site.register(DClass)
admin.site.register(DListClass, DListClassAdmin)
View Code
DClass表創建D1、D2實例,DListClass表創建d1、d11兩個實例關聯D1實例,創建d2、d22兩個實例關聯D2實例
0
當刪除DClass的D1實例時,與它相關聯的DListClass表的d1、d11實例的d_name字段會被設置為默認值,此處為NULL
0
 
  • on_delete=models.DO_NOTHING:什么事兒都不做?如果你的數據庫后端強制引用完整性,它將引發一個IntegrityError ,除非你手動添加一個ON DELETE 約束給數據庫

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM