Django之靜態文件,中間件,admin後臺管理;其中,靜態文件 包括靜態文件的使用,動態生成靜態文件的路徑;中間件包括 使用中間件,使用中間件防爬蟲ip案例;admin後臺管理 包括 admin的使用,列表頁選項,編輯頁選項等。 ...
Django1.8.2中文文檔:Django1.8.2中文文檔
靜態文件
靜態文件的使用
在 網頁使用的css文件,js文件和圖片等叫做靜態文件。
1)在項目下新建靜態文件夾 static。
2) 配置靜態文件所在的物理目錄。Settings.py
- STATIC_URL設置訪問靜態文件對應的url。
- STATICFILES_DIRS設置靜態文件所在的物理目錄。
動態生成靜態文件的路徑
即不管你的 STATIC_URL 怎麼變,也對頁面上的靜態文件url獲取沒影響
settings.py
# 設置訪問靜態文件的url地址 # http://127.0.0.1:8000/static/images/mm.jpg,通過這個,可以直接訪問圖片 STATIC_URL = '/static/' # STATIC_URL = '/abc/' # 設置靜態文件存放的物理目錄 # Django找靜態文件的順序:先去配置的 STATICFILES_DIRS 下麵去找,找不到就去應用下麵的static下麵找 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
static_test.html
<!DOCTYPE html> {% load staticfiles %} <html lang="en"> <head> <meta charset="UTF-8"> <title>靜態文件測試</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <img src="/static/images/mm.jpg" alt="mm"> <img src="/abc/images/mm.jpg" alt="mm"> 動態獲取 STATIC_URL,拼接靜態文件路徑:<br> <img src="{% static 'images/mm.jpg' %}" alt="mm"> </body> </html>
配套函數
def static_test(request): """靜態文件""" return render(request, 'booktest/static_test.html')
中間件
中間件函數是django框架給我們預留的函數介面,讓我們可以干預請求和應答的過程。
使用中間件
1)在應用中新建middleware.py文件。
2)定義中間件類。
在類中定義中間件預留函數。
- __init__:伺服器響應第一個請求的時候調用。
- process_request:是在產生request對象,進行url匹配之前調用。
- process_view:是url匹配之後,調用視圖函數之前。
- process_response:視圖函數調用之後,內容返回給瀏覽器之前。
- process_exception:視圖函數出現異常,會調用這個函數。
如果註冊的多個中間件類中包含process_exception函數的時候,調用的順序跟註冊的順序是相反的。
3)註冊中間件類。
使用中間件進行登錄判斷案例
獲取瀏覽器端的ip地址,使用request對象的META屬性:
request.META['REMOTE_ADDR']
需求
當我們需要禁用某些惡意ip的訪問時,需要獲取用戶ip,然後建立一個禁止ip列表,判斷ip是否在禁止列表中,如果是惡意ip,則禁止進入,
否則返迴響應的頁面,誠然,我們可以定義一個裝飾器來對每個函數進行判斷,但這並不是最佳的選擇,我們可以使用中間件。
單個函數判斷
def index(request): """首頁""" user_ip = request.META['REMOTE_ADDR'] print(user_ip) if user_ip in EXCLUDE_IPS: return HttpResponse("<h2>Forbidden</h2>") return render(request, 'booktest/index.html')
裝飾器判斷
def ban_ip(view_func): """用來禁止惡意ip的裝飾器""" def wrapper(request, *args, **kwargs): user_ip = request.META['REMOTE_ADDR'] print(user_ip) if user_ip in EXCLUDE_IPS: return HttpResponse("<h2>Forbidden</h2>") else: return view_func(request, *args, **kwargs) return wrapper @ban_ip def index(request): """首頁""" return render(request, 'booktest/index.html')
中間件步驟
- 1.在應用下新建一個middleware.py文件,名字隨意,但一般用這個。
- 2.編寫中間件代碼;
- 3.在settings中註冊中間件;
中間件判斷
from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponse class BanIpMiddleware(MiddlewareMixin): """中間件類""" EXCLUDE_IPS = ['127.0.0.1'] @staticmethod def process_view(request, view_func, *args, **kwargs): """視圖函數調用之前會調用""" user_ip = request.META['REMOTE_ADDR'] if user_ip in BanIpMiddleware.EXCLUDE_IPS: return HttpResponse("<h2>Forbidden</h2>")
註冊中間件
MIDDLEWARE = [ 'booktest.middleware.BanIpMiddleware', ]
中間件執行順序
中間件的執行順序一般是按照在settings文件裡面的註冊順序來的,特殊情況是如果註冊的多個中間件類中包含process_exception函數的時候,調用的順序跟註冊的順序是相反的。
__init__只在伺服器重啟之後,第一個請求時調用,後面的請求都不會再調用了;
中間件執行順序示例代碼
class TestMiddleware(MiddlewareMixin): """中間件類""" def __init__(self, get_response=None): """伺服器重啟之後,接收第一個請求時調用""" # get_response參數是必需的,這個參數指的是下一個中間件或者view函數(如果是最後一個中間件)。 super().__init__() self.get_response = get_response print("-----init-----") @staticmethod def process_request(request): """產生request對象之後,url匹配之前調用""" print("-----process_request-----") @staticmethod def process_view(request, view_func, *args, **kwargs): """url匹配之後,視圖函數調用之前調用""" print("-----process_view-----") @staticmethod def process_response(request, response): """視圖函數之後,應答返回瀏覽器之前""" print("-----process_response-----") return response # 執行結果: # -----init----- # -----process_request----- # -----process_view----- # -----process_response----- class ExceptionTest1Middleware(MiddlewareMixin): @staticmethod def process_exception(request, exception): """視圖函數發生異常時調用""" print("-----process_exception1-----") print(exception) class ExceptionTest2Middleware(MiddlewareMixin): @staticmethod def process_exception(request, exception): """視圖函數發生異常時調用""" print("-----process_exception2-----")
admin後臺管理
admin的使用
- 1) 本地化。語言和時區本地化。
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai'
- 2) 創建超級管理員。
python mange.py createsuperuser
- 3) 註冊模型類。
- 4)
- 4.1.自定義管理頁面。
- 4.2.自定義模型管理類。
- 4.3.註冊模型類的時候給register函數添加第二個參數,就是自定義模型管理類的名字。
列表頁選項
列表頁選項示例代碼
models.py
class AreaInfo(models.Model): """地區模型類""" # 地區名稱 atitle = models.CharField(verbose_name="地區名", max_length=20) # 自關聯屬性 aParent = models.ForeignKey('self', null=True, blank=True) # 在admin點進去表之後顯示地區名 def __str__(self): return self.atitle # 定義title列,提供顯示atitle def title(self): return self.atitle title.admin_order_field = 'id' # 定義title列的排序方式 title.short_description = '地區名稱' # 定義title列顯示的列名 def parent(self): if self.aParent is None: return '' return self.aParent.atitle parent.short_description = '父級地區名稱'
admin.py
class AreaInfoAdmin(admin.ModelAdmin): """地區模型管理類""" list_per_page = 10 # 指定每頁顯示10條數據 list_display = ['id', 'atitle', 'title', 'parent'] # 指定頁面上展示的內容 actions_on_bottom = True # 開啟下麵的action框 actions_on_top = False # 關閉上建的action框 list_filter = ['atitle'] # 頁表右側的過濾蘭 search_fields = ['atitle'] # 列表頁上方的搜索框 admin.site.register(models.AreaInfo, AreaInfoAdmin)
註:list_display不僅可以寫模型類的屬性,還可以寫方法;
顯示效果
編輯頁選項
初始效果圖
fields控制顯示欄位順序
class AreaInfoAdmin(admin.ModelAdmin): fields = ['aParent', 'atitle'] # 控制編輯頁中 顯示欄位的順序
改變順序後
分組顯示
class AreaInfoAdmin(admin.ModelAdmin): """地區模型管理類""" fieldsets = ( ('基本', {'fields': ['atitle']}), ('高級', {'fields': ['aParent']}) )
分組顯示效果圖
應註意 ,fields和fieldsets不能同時使用。
關聯對象/控制顯示該地區下麵的子級地區
塊嵌入
# 塊嵌入 class AreaStackedInline(admin.StackedInline): # 寫多類的名稱 model = models.AreaInfo # 關聯子對象 extra = 2 # 控制多餘的行數/額外編輯2個子對象 class AreaInfoAdmin(admin.ModelAdmin): """地區模型管理類""" inlines = [AreaStackedInline]
表嵌入
class AreaTabularInline(admin.TabularInline): model = models.AreaInfo # 關聯子對象 extra = 2 # 控制多餘的行數/額外編輯2個子對象 class AreaInfoAdmin(admin.ModelAdmin): """地區模型管理類""" inlines = [AreaStackedInline]
表嵌入效果圖
塊嵌入和表嵌入其實顯示的內容是一樣的,知識顯示樣式不同而已。