• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • web框架之Django基礎

    本節內容

    • HTTP協議
    • wsgi協議和wsgiref模塊
    • Djano基本流程和配置
    • Django的路由系統
    • Django靜態文件
    • template模板語言

    一 HTTP協議

     1 HTTP簡介

    HTTP是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫。它的發展是萬維網協會(World Wide Web Consortium)和Internet工作小組IETF(Internet Engineering Task Force)合作的結果,(他們)最終發布了一系列的RFC,RFC 1945定義了HTTP/1.0版本。
    其中最著名的就是RFC 2616。RFC 2616定義了今天普遍使用的一個版本——HTTP 1.1。
    HTTP協議具有如下特點:
    (1) 基于TCP的80端口
    (2) 基于請求-響應模式
    (3) 無狀態保存,不對請求和響應之間的通信狀態進行保存
    (4) 無連接,限制每次連接至處理一個請求,處理完成后即斷開連接

    2 HTTP中的方法

    GET:從一個服務器獲取一個資源
    HEAD:只從服務器獲取文檔響應首部,而不獲取響應內容
    POST:向服務器發送要處理的數據
    PUT:將請求的主體部分直接存儲在服務器上
    DELETE:請求刪除服務器上指定的文檔
    TRACE:追蹤請求到達服務器中間經過的代理服務器
    OPTIONS:請求服務器返回對指定資源支持使用的請求方法

     3 HTTP的報文格式

    請求:request
    響應:response
    request報文
    <method> <request-URL> <version>
    <headers>

    <entity-body>

    resposene報文
    <version> <status><reason-phrase>
    <headers>

    <entity-boday>

     4 HTTP中的響應狀態碼

    三位數字,如200,301,203,404,502,描述標記請求發生的狀況

    狀態代碼:
    1XX:純信息
    2XX:成功類的信息
    3xx:重定向類信息
    4xx:客戶端錯誤類的信息
    5xx:服務器端錯誤類信息

    常用狀態碼:
    200:成功,請求的所有數據通過響應報文entity-body部分發送
    301:請求的URL資源已被刪除,但在響應報文中通過Location指明了資源現在的位置,Moved Permanently
    302:與301相似,但在響應報文中通過Location指明資源現在所處臨時新位置
    304:客戶端發出了條件式請求,但服務器的資源未曾發生改變,則通過響應此響應狀態碼通知客戶端:Not Modified
    401:需要輸入賬號和密碼認證方能訪問資源:Unauthorized
    403:請求被禁止;Forbidden
    404:服務器無法找到客戶端請求的資源;Not Found
    500:服務器內部錯誤;Internal Server Error
    502:代理服務器從后端服務器收到了一條偽響應

    5 HTTP請求頭部和響應頭部包含的內容

    通用首部:
    Date:報文的創建時間
    Connetction:連接方式,如keep-alive,close
    Via:顯示報文經過的中間節點
    Cache-Control:控制緩存

    請求首部
    Accpet:通知服務器自己可接受的媒體類型
    Accept-Charset:通知服務器自己可接受的字符集
    Accept-Encoding:通知服務器自己接受的編碼格式,如GZIP
    ACCPT-Language:接受的語言
    Host:請求的服務器名稱和端口號
    Rerferer:包含當前正在請求資源的上一級資源
    User-Agent:客戶端代理
    If-Modified-Since:自從指定的時間之后,請求的資源是否發生過修過
    If-Unmodified-Since:自從指定的時間之后,請求的資源是否未過修過
    If-None-Mathc:本地緩存中存儲的文檔的Etagb標簽是否與服務器ETG不匹配
    Authorization:向服務器端發送認證信息,如賬號密碼
    Cookie:客戶端向服務器端發送Cookie標識
    Proxy-Authorization:向代理服務器認證

    響應首部
    Age:響應持續時長
    Server:服務器程序的軟件名稱和版本
    協商首部:某資源多種表示方法時使用
    Accpet-Ranges:服務器可接受的請求范圍類型
    Vary:服務器查看其它首部列表
    安全響應首部:
    Set-Cookie:向客戶端設置cookie
    www.Authenticate:來自服務器對客戶端的質詢認證表單

    6 Cookie和Session

    Cookie和Session都為了用來保存狀態信息,都是保存客戶端狀態機制,都是為了解決HTTP無狀態的問題而產生
    Session可以用Cookie來實現,也可以用URL回寫的機制來實現。用Cookie來實現的Session可以認為是對Cookie更高級的應用。

    Cookie和Session有以下明顯的不同點:
       (1) Cookie將狀態保存在客戶端,Session將狀態保存在服務端
       (2) Cookie是服務器在本地機器上存儲的小段文本并隨每一個請求發送至同一個服務器,cookie最早在RFC2109中實現,后續RFC2965做了增強。網絡服務器用HTTP頭向客戶端發送cookies,在客戶終端,瀏覽器解析這些cookies并將它們保存為一個本地文件,它會自動將同一服務器的任何請求縛上這些cookies。Session并沒有在HTTP的協議中定義;
       (3) Session是針對每一個用戶的,變量值保存在服務器上,用一個sessionID來區分是哪個用戶session變量,這個值是通過用戶的瀏覽器在訪問的時候返回給瀏覽器,當客戶禁用cookie時,這個值也可能設置為由get來返回給服務器。
       (4) 就安全性來說:當你訪問一個使用session 的站點,同時在自己機子上建立一個cookie,建議在服務器端的SESSION機制更安全些.因為它不會任意讀取客戶存儲的信息。

    關于session和Cookie在Django的具體使用請見:

     

    7 通過sokcet 建立一個HTTP響應

    def create_sk():
    	server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    	server.bind(('127.0.0.1', 8080))
    	server.listen(5)
    	return server
    		
    def handle_request(server):
    	print('server start....')
    	while 1:
    		conn,addr = server.accept()
    		data = conn.recv(1024)
    		print(data)             # 接收到 http請求頭部
    		conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
    		conn.send(b'<h1>hello world</h1>')
    
    def run():
    	sk = create_sk()
    	handle_request(sk)
    
    if __name__ == '__main__':
    	run()
    

      

     二 wsgi協議和wsgiref模塊

     

    WSGI:Web Server Gateway Interface,是Python應用程序或框架和Web服務器之間的一種接口,而wsgiref模塊就是python基于wsgi協議開發的服務模塊。
    自己定義一個web框架所需的幾個主要文件
        1 urls.py:路徑與視圖函數映射關系 --- url控制器
        2 views.py: 視圖函數,固定一個形式參數:environ
        3 templates文件夾: html模板文件
        4 models:在項目啟動前創建表結構

    通過wsgire模塊自己搭建一個web服務器

    main.py  主程序	:
    
    from wsgiref.simple_server import make_server
    import urls
    
    def application(environ,start_response):
    	path = environ["PATH_INFO"]  # 獲取當前請求路徑
    	print('server start')
    	start_response('200 OK', [('Content-Type', 'text/html')])
    	urls_list = urls.routers()
    	func = None
    	for i in urls_list:
    	if path == i[0]:
    		func = i[1]
    	if func:
    		return func()
    	else:
    		return [b'<h1>404 not found</h1>']
    			
    urls.py 控制器
    from view import *
    def routers():
    	urls_list = [
    			   ('/login', login),
    			]
    	return urls_list
    		
    view.py 視圖函數
    	def login():
    		with open('templates/login.html', 'rb') as f:
    		data = f.read()
    		return [data]
    
    http_server = make_server('', 8080 ,application)
    http_server.serve_forever()
    

     

    三 Djano基本流程和配置

    1 MVC與MTV模型


    MVC


    Web服務器開發領域里著名的MVC模式,所謂MVC就是把Web應用分為模型(M),控制器(C)和視圖(V)三層,他們之間以一種插件式的、松耦合的方式連接在一起,
    模型負責業務對象與數據庫的映射(ORM),視圖負責與用戶的交互(頁面),控制器接受用戶的輸入調用模型和視圖完成用戶的請求

     

    MTV

    Django的MTV模式本質上和MVC是一樣的,也是為了各組件間保持松耦合關系,只是定義上有些許不同,Django的MTV分別是值:
        M 代表模型(Model):負責業務對象和數據庫的關系映射(ORM)。
        T 代表模板 (Template):負責如何把頁面展示給用戶(html)。
        V 代表視圖(View):負責業務邏輯,并在適當時候調用Model和Template。
        除了以上三層之外,還需要一個URL分發器,它的作用是將一個個URL的頁面請求分發給不同的View處理,View再調用相應的Model和Template

    2 創建一個django project

    danjgo-admin.py startproject mysite
    manage.py ----- Django項目里面的工具,通過它可以調用django shell和數據庫等
    settings.py ---- 包含樂項目默認設置, 包括數據庫信息,調試標志及其他一些工作的表露
    urls.py ---- 負責把URL模式映射到應用程序

    3 Django的其他常用命令

    python manage.py runserver ip:port (啟動服務器,默認ip和端口為http://127.0.0.1:8000/)
    python manage.py startapp appname (新建 app)
    python manage.py syncdb (同步數據庫命令,Django 1.7及以上版本需要用以下的命令)
    python manage.py makemigrations (顯示并記錄所有數據的改動)
    python manage.py migrate (將改動更新到數據庫)
    python manage.py createsuperuser (創建超級管理員)
    python manage.py dbshell (數據庫命令行)
    python manage.py (查看命令列表)

    四 Django的路由系統 

    每一個Django項目中都會有一個urls.py的文件,它的作用是根據用戶請求的url調用不同視圖函數來給用戶返回不同頁面
     urlpatterns = [
           path(url,view函數,參數,別名)
           repath(正則表達式,view函數,參數,別名)
      ]   
    參數說明:
       (1) 一個正則表達式字符串,或者一個url
       (2) 一個可以調用的對象,通常稱為一個視圖函數,
       (3) 可選的要傳遞給視圖函數的默認參數(字典形式)
       (4) 一個可選的name參數

    1 示例:

    from django.contrib import admin
    from django.urls import path,re_path
    import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        re_path(r'^article/2001$', views.article_year), # 匹配正則匹配到的路徑
        re_path(r'^article/([0-9]{4})', views.article_year),
        re_path(r'^article/([0-9]{4})/([0-9]{2})/$', views.article_month),
        re_path(r'^article/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})',views.article_month), # 正則命名,視圖函數的形參要與正則命名的一致
    ]

    注意事項:
    (1) 要捕獲URL中的值,用括號括起來,會當作參數傳入視圖函數
    (2) 沒有必要添加一個斜線,因為每個URL都有。例如:^articles不是^/articles。
    (3) 在'r'前面的每個正則表達式字符串中是可選的,但建議。它告訴Python字符串是“原始” -沒有什么字符串中應該進行轉義。

     2 多個APP進行路由分發(Including)

    如果一個Django項目里面有多個APP那么大家共用一個url路由很容易造成混淆,于是使用include分發讓每個APP擁有自己單獨的url

    from django.conf.urls import re_path,include
    from django.contrib import admin
    from app1 import views
    urlpatterns = [
    	      re_path(r'^app1/',include('app1.urls')),
    	      re_path(r'^app2/',include('app1.urls')),  #注意include的是字符串形式的 文件路徑;
    	      re_path(r'^',views.error),
    	]

    3 使用url別名的示例 

    url中還支持name參數的配置,如果配置了name屬性,在模板的文件中就可以使用name值來代替相應的url值.
    urlpatterns = [
    		re_path(r'^index',views.index,name='bieming'),
    		re_path(r'^admin/', admin.site.urls),
    		re_path(r'^articles/2003/$', views.special_case_2003),
    		re_path(r'^articles/([0-9]{4})/$', views.year_archive),
    		re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    		re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
    		]
    ###################
    def index(req):
    	if req.method=='POST':
    		username=req.POST.get('username')
    		password=req.POST.get('password')
    		if username=='alex' and password=='123':
    			return HttpResponse("登陸成功")
    		return render(req,'index.html')
    
    #####################
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Title</title>
    </head>
    <body>
    	{#     <form action="/index/" method="post">#}
    	{#     這里只要使用bieming即可代替/index #}
    	<form action="{% url 'bieming' %}" method="post">
    		 用戶名:<input type="text" name="username">
    		密碼:<input type="password" name="password">
    	        <input type="submit" value="submit">
    	</form>
    </body>
    </html>

      4 名稱空間

    名稱空間是表示標識符的可見范圍,一個標識符可在多個命名空間中定義,它在不同命名空間中的含義是互不相干的,
    在一個新的命名空間中可定義任何標識符,它們不會與任何已有的標識符發生沖突,因為已有的定義都處于其他命名 空間。

    由于name沒有作用域,Django在反解析URL時,會在項目全局順序搜索,當查找到第一個name指定URL時,立即返回
    我們在開發項目時,會經常使用name屬性反解除URL,當不小心在不同的app的urls中定義相同的name時,可能會導致URL反解錯誤,為了避免這種情況引入了命名空間

     

    project的urls.py:
    	urlpatterns = [
    		 re_path(r'^app1/',include(('app1.urls',"app01")),
    		 re_path(r'^app2/',include(('app2.urls',"app02")),  
    		]
    							 
    app01.urls
    	urlpatterns = [
    		re_path(r'^index/',index,name="index"),
    		]
    		
    app02.urls
    	urlpatterns = [
    			re_path(r'^index/',index,name="index"),
    		 ]
    		
    app01.views
    	from django.core.urlresolvers import reverse
    	def index(request)
    		return HttpResponse(reverse("app01:index"))
    			
    app02.views
    	from django.core.urlresolvers import reverse
    	def index(request)
    	       return HttpResponse(reverse("app02:index")	
    

     

    5 django2.0中 path的用法

    from django.urls import path
    from . import views
    	urlpatterns = [
    		path('articles/2003/, views.special_case_2003),
    		path('articles/<int:year>/', views.year_archive),
    		path('articles/<int:year>/<int:month>/',views.moutn_archive),
    		path('articles/<int:year>/<int:month>/<slug>/, views.article_detail),
    		]
    基本規則:
    	(1) 使用尖括號(<>)從url中捕獲值。
    	(2) 捕獲值中可以包含一個轉化器類型(converter type),比如使用<int:name>捕獲一個整數變量,如果沒有轉化器,將匹配任何字符串,也包括'/'字符
    	(3) 無需添加前倒斜杠
    

     

    Django默認支持的轉化器
        (1) str,匹配除了路徑分隔符(/)之外的飛車空字符串,這是默認的形式
        (2) int,匹配正整數,包含0
       (3) slug,匹配字母,數字及橫杠,下劃線組成的字符串
       (4) uuid,匹配格式化uuid,如0745194d3-6885-417e-a8a8-6c931e272f00
       (5) path,匹配任何非空字符串,包含了路徑分隔符

    自定義轉換器
    對于一些復雜的使用,可以自定義裝換器。轉換器是一個類或接口,它的要求有三點:
        regex類屬性,字符串類型
        to_python(self,value)方法,value是由類屬性regex所匹配到的字符串,返回具體的Python變量值,以供Django傳遞到對應的視圖函數中
        to_url(self,value)方法,和to_python相反,value是一個具體的Python變量值,返回其字符串,通常用于url反向引用

    示例:

    class FourDigYearConverter:
        regex = '[0-9]{4}'
                        
        def to_python(self,value):
            return int(value)
        def to_url(self,value):
            return '%04d' %value
    
    使用register_converter將其注冊到URL配置中
    from django.urls import register_converter,path
    from . import converters, views            # 自己寫的類模塊導入盡量
    register_converter(converters.FourDigYearConverter, 'yyyy')
    urlpatterns = [
                path('articles/2003/', views.special_case_2003),
                path('articles/<yyyy:year>', views.path_month)
        
            ]

     

    五 Django靜態文件

    1 static靜態文件

    我們在項目中一般情況下html模板都需要引入js css等靜態文件來渲染網頁,下面會介紹Django引入這些靜態文件的方式:
         1 首先先要在項目中創建一個名叫static的文件夾
         2 在Django的settings中添加一行配置, 拼接static文件夾的路徑
                   STATICFILES_DIRS = [
                           os.path.join(BASE_DIR,"static")
                        ]
        3 在html直接引入static路徑下的內容
              <script src="/static/jquery-3.3.1.js"></script>

    2 media靜態文件

    Media配置

        在項目的應用下生成一個media文件夾
        在settings下配置:MEDIA_ROOT = os.path.join(BASE_DIR,"media")

        如果用戶一旦配置了MEDIA_ROOT:
        avatar_obj=request.FIELS.get("avatar")
        user_obj = UserInfo.objects.create_user(username=user,password=pwd,email=email,avatar=avatar_obj)
        Django會將文件對象下載到MEDIA_ROOT中的avatar文件夾中(如果沒有avatar,Django會自動創建), user_obj的avatar存的是文件對象

    Meida 配置值MEDIA_URL:

       讓瀏覽器直接訪問到media中的數據
       在settings.py里配置MEDIA_URL="/meida"
       # media配置
       from django.views.static import serve
       from cnblog import settings
       re_path(r"media/(?P<path>.*)$", serve, {"document_root":settings.MEDIA_ROOT})

    六 template模板語言

    1 模板之過濾器

    語法
        {{ obj|filter_name:param }}
    default
        如果一個變量是false或者為空,使用給定的默認值,否則使用變量的值.
        {{ value|default:"nothing" }}
    length
        返回值的長度,它對字符串和列表都起作用。例如
        {{ value|length }}
        如果value是['a','b','b','d']那么輸出4
    filesizeformat
        將格式化為一個"人類可讀的"文件尺寸(例如13kb,4.1mb,1024bytes等待).例如:
        {{ value|filesizeformat }}
        如果value是123456789,輸出將會是117.7MB
    date
        如果 value = datetime.datetime.now()
        {{ value|date:"Y-m-d" }}
    slice
        如果 value = "hello world"
       {{ value|slice:"2-1" }}
    truncatechars
        如果字符串字符多于指定的字符數量,那么會被截斷。截斷字符串可以翻譯的省略號序列("...")結尾
        參數:要截斷的字符數
        {{ value|truncatechars:9 }}
    safe
         Django的模板中會對HTML標簽和JS等語法進行自動轉義,但是有的時候我們不希望這些HTML元素被轉義,
        在Django中關系HTML自動轉義有兩種方式,如果是一個單獨的變量我們可以通過過濾"|safe"的方式告訴Django這段代碼是安全的不必轉義
        value = "<a href="">點擊</a>
        {{ value|safe }}

    2 模板之標簽

    標簽看起來是這樣的:{% tag %}。標簽比變量更加復雜:一些在輸出中創建文件,一些通過循環或邏輯來控制流程,
    一些加載其后的變量將使用到的額外信息添加到模板中。

    for標簽
    遍歷每一個元素
        {% for person in person_list %}
            <p>{{ pserson.name }} <p>
        { % endfor %}
                
    可以利用{% for obj in list reversed %}反向完成循環。
        遍歷一個字典:
            {% for key,val in dic.items %}
                <p>{{ key }}:{{ val }}<p>
            {% endfor % }
            
    for ... empty
        for標簽帶有一個可選的{% empt %}從句,以便在給出的組是空的或者沒有找到時,可以有所操作
        {% for person in pserson_list %}
            <p>{{ person.name }}</p>
                    
        {% enpty %}
            <p>sorry,no person here</p>
        {% endfor %}
            
    if 標簽
        {% if %}會對一個變量求值,如果他的值是True(存在,不為空且不是boolean類型的false值),對應的內容塊會輸出
                
    {% if num >100 or num <0 %}
        <p>無效</p>
    {% elif num > 80 and num < 100 %}
        <p>優秀</p>
    {% else %}
        <p>湊合吧</p>
    {% endif %}
            
    with
        使用一個簡單的名字緩存一個復雜的變量。
    例如:
        {% with total=business.employees.count %}
            {{ total }} employee{{ total|pluralize }}
        {% endwith %}
    

     3 自定義標簽

    (1) 在應用目錄下創建一個templatetags目錄(必須)
    (2) 創建任意.py文件, 如:add100.py

    from django import template
    from django.utils.safestring import mark_safe
                
    register = template.Library() # register是固定變量名,不能改變
                
    @register.simple_tag
    def my_add100(value1)
        return value1 + 100
                    
    @register.simple_tag
    def my_input(id,arg):
        result = "<input type="text" id='%s' class='%s'/>" %id(id,arg,)
        return make_server(result)
                    
    @register.filter            # 自定義過濾器
    def multi_filter(x,y):
        return x*y

    #注意:自定義標簽和自定義過濾器的區別在于標簽可以傳多個參數而過濾器最多只能傳2個但是過濾器可以使用if語句

    (3) 在使用自定義simple_tag的html文件導入之前創建add100.py文件夾
        {% load add100 %}

    (4) 使用simple_tag
        {% my_add100 5%}
        {% my_input 'id_username' 'hide'%}
    (5) 在setting中配置當前app, 不然django無法找到自定義的simple_tag
        INSTALLED_APPS = "app01".

    4 模板之繼承

    (1) 首先先將一些公共的版塊寫成一個基礎模板, 如果模一塊內容需要擴展,{% block contnet %} {% endblock %},相當于留了一些空間等待子模板重寫里面的內容
    (2) 在子模板的第一行引入模板{% extends 'base.html' %}
    (3) 在子模塊引入{% block contnet %} {% endblock %}然后重寫里面的內容

    版權聲明:本文為weixin_33755649原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_33755649/article/details/94193257

    智能推薦

    python web框架之Django隨筆總結

    一.Django中url多級路由總結 1.1 django中多級路由映射 django項目中如果一個項目內又分多個app,那么合理的結構是每一個app都應該有一層api路由,通過一級路由映射到當前app中。 django中所有路由的入口在與settting.py同級的urls.py下,所有applications接口接收到的請求首先會轉發到此入口,然后根據此入口中的路由規則然后將url請求轉發到對...

    python Django之Web框架本質 (2)

    文章目錄 一.Web應用本質 1.socket本質 二.發送HTTP協議、響應 1.HTTP協議 2.HTTP發送響應 靜態網頁 動態網頁 三.jinja2模板渲染 一.Web應用本質 為了了解Django的客戶端與服務端的交互原理,我們需要了解Web應用的本質方便以后更加的理解Django原理 在Web應用中,服務器把網頁傳給瀏覽器,實際上就是把網頁的HTML代碼發送給瀏覽器,讓瀏覽器顯示出來。...

    Python的web框架Django基礎學習(1)

    1.首先PIP安裝一下 2.可通過pycharm來創建一個Django工程 setting.py中可以小設置一下,例如訪問的ip,語言,時間格式  3.因為Django內置了一個開發服務容器,所以可以通過命令行來運行一下,運行生成項目的manage.py文件 就可以通過本地8000端口訪問一下了 4.訪問后提示我們需要創建一個程序 可以通過上述命令  來創建一個目錄。 &nbs...

    Python Web框架: Django基礎與項目搭建

    框架要點 1. Web應用程序處理流程 2. Web程序框架的意義 用于搭建Web應用程序 免去不同Web應用相同代碼部分的重復編寫,只需關心Web應用核心的業務邏輯實現 3. Web應用程序的本質 接收并解析HTTP請求,獲取具體的請求信息 處理本次HTTP請求,即完成本次請求的業務邏輯處理 構造并返回處理結果——HTTP響應 4. Web框架學習方法 如何搭建工程程序 ...

    【Django】Web框架本質

    原文:https://blog.csdn.net/qq_41964425/article/details/82841116 文章目錄 根據不同的路徑返回不同的內容 普通版 函數版 函數進階版 返回具體的HTML文件 讓網頁動態起來 服務器和應用程序 wsgiref 模塊 我們可以這樣理解:所有的Web應用本質上就是一個socket服務端,而用戶的瀏覽器就是一個socket客服端。 這樣我們就可以自...

    猜你喜歡

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡