本節內容: javascript
Django中默認支持Session,其內部提供了5種類型的Session供開發者使用:html
一、數據庫Sessionjava
Django默認支持Session,而且默認是將Session數據存儲在數據庫中,即:django_session 表中。 a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默認) SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認) SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(默認) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時(默認) SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存(默認) b. 使用 def index(request): # 獲取、設置、刪除Session中數據 request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在則不設置 del request.session['k1'] # 全部 鍵、值、鍵值對 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 用戶session的隨機字符串 request.session.session_key # 將全部Session失效日期小於當前日期的數據刪除 request.session.clear_expired() # 檢查 用戶session的隨機字符串 在數據庫中是否 request.session.exists("session_key") # 刪除當前用戶的全部Session數據 request.session.delete("session_key") request.session.set_expiry(value) * 若是value是個整數,session會在些秒數後失效。 * 若是value是個datatime或timedelta,session就會在這個時間後失效。 * 若是value是0,用戶關閉瀏覽器session就會失效。 * 若是value是None,session會依賴全局session失效策略。
二、緩存Sessionpython
a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的緩存別名(默認內存緩存,也能夠是memcache),此處別名依賴緩存的設置 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時 SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存 b. 使用 同上
三、文件Sessionjquery
a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時 SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存 b. 使用 同上
四、緩存+數據庫Sessiongit
數據庫用於作持久化,緩存用於提升效率 a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 b. 使用 同上
五、加密cookie Sessionajax
a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 b. 使用 同上
擴展:Session用戶驗證正則表達式
1 def login(func): 2 def wrap(request, *args, **kwargs): 3 # 若是未登錄,跳轉到指定頁面 4 if request.path == '/test/': 5 return redirect('http://www.baidu.com') 6 return func(request, *args, **kwargs) 7 return wrap
1、簡介數據庫
django爲用戶實現防止跨站請求僞造的功能,經過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成。而對於django中設置防跨站請求僞造功能有分爲全局和局部。django
全局:
中間件 django.middleware.csrf.CsrfViewMiddleware
局部:
注:from django.views.decorators.csrf import csrf_exempt,csrf_protect
2、應用
一、普通表單
veiw中設置返回值: return render_to_response('Account/Login.html',data,context_instance=RequestContext(request)) 或者 return render(request, 'xxx.html', data) html中設置Token: {% csrf_token %}
二、Ajax
對於傳統的form,能夠經過表單的方式將token再次發送到服務端,而對於ajax的話,使用以下方式。
view.py
1 from django.template.context import RequestContext 2 # Create your views here. 3 4 5 def test(request): 6 7 if request.method == 'POST': 8 print request.POST 9 return HttpResponse('ok') 10 return render_to_response('app01/test.html',context_instance=RequestContext(request))
text.html
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 {% csrf_token %} 9 10 <input type="button" onclick="Do();" value="Do it"/> 11 12 <script src="/static/plugin/jquery/jquery-1.8.0.js"></script> 13 <script src="/static/plugin/jquery/jquery.cookie.js"></script> 14 <script type="text/javascript"> 15 var csrftoken = $.cookie('csrftoken'); 16 17 function csrfSafeMethod(method) { 18 // these HTTP methods do not require CSRF protection 19 return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 20 } 21 $.ajaxSetup({ 22 beforeSend: function(xhr, settings) { 23 if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 24 xhr.setRequestHeader("X-CSRFToken", csrftoken); 25 } 26 } 27 }); 28 function Do(){ 29 30 $.ajax({ 31 url:"/app01/test/", 32 data:{id:1}, 33 type:'POST', 34 success:function(data){ 35 console.log(data); 36 } 37 }); 38 39 } 40 </script> 41 </body> 42 </html>
因爲Django是動態網站,全部每次請求均會去數據進行相應的操做,當程序訪問量大時,耗時必然會更加明顯,最簡單解決方式是使用:緩存,緩存將一個某個views的返回值保存至內存或者memcache中,5分鐘內再有人來訪問時,則再也不去執行view中的操做,而是直接從內存或者Redis中以前緩存的內容拿到,並返回。
Django中提供了6種緩存方式:
一、配置
a、開發調試
1 # 此爲開始調試用,實際內部不作任何操做 2 # 配置: 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎 6 'TIMEOUT': 300, # 緩存超時時間(默認300,None表示永不過時,0表示當即過時) 7 'OPTIONS':{ 8 'MAX_ENTRIES': 300, # 最大緩存個數(默認300) 9 'CULL_FREQUENCY': 3, # 緩存到達最大個數以後,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) 10 }, 11 'KEY_PREFIX': '', # 緩存key的前綴(默認空) 12 'VERSION': 1, # 緩存key的版本(默認1) 13 'KEY_FUNCTION' 函數名 # 生成key的函數(默認函數會生成爲:【前綴:版本:key】) 14 } 15 } 16 17 18 # 自定義key 19 def default_key_func(key, key_prefix, version): 20 """ 21 Default function to generate keys. 22 23 Constructs the key used by all other methods. By default it prepends 24 the `key_prefix'. KEY_FUNCTION can be used to specify an alternate 25 function with custom key making behavior. 26 """ 27 return '%s:%s:%s' % (key_prefix, version, key) 28 29 def get_key_func(key_func): 30 """ 31 Function to decide which key function to use. 32 33 Defaults to ``default_key_func``. 34 """ 35 if key_func is not None: 36 if callable(key_func): 37 return key_func 38 else: 39 return import_string(key_func) 40 return default_key_func
b、內存
1 # 此緩存將內容保存至內存的變量中 2 # 配置: 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 6 'LOCATION': 'unique-snowflake', 7 } 8 } 9 10 # 注:其餘配置同開發調試版本
c、文件
1 # 此緩存將內容保存至文件 2 # 配置: 3 4 CACHES = { 5 'default': { 6 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 7 'LOCATION': '/var/tmp/django_cache', 8 } 9 } 10 # 注:其餘配置同開發調試版本
d、數據庫
1 # 此緩存將內容保存至數據庫 2 3 # 配置: 4 CACHES = { 5 'default': { 6 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 7 'LOCATION': 'my_cache_table', # 數據庫表 8 } 9 } 10 11 # 注:執行建立表命令 python manage.py createcachetable
e、Memcache緩存(python-memcached模塊)
1 # 此緩存使用python-memcached模塊鏈接memcache 2 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 6 'LOCATION': '127.0.0.1:11211', 7 } 8 } 9 10 CACHES = { 11 'default': { 12 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 13 'LOCATION': 'unix:/tmp/memcached.sock', 14 } 15 } 16 17 CACHES = { 18 'default': { 19 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 20 'LOCATION': [ 21 '172.19.26.240:11211', 22 '172.19.26.242:11211', 23 ] 24 } 25 }
f、Memcache緩存(pylibmc模塊)
1 # 此緩存使用pylibmc模塊鏈接memcache 2 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 6 'LOCATION': '127.0.0.1:11211', 7 } 8 } 9 10 CACHES = { 11 'default': { 12 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 13 'LOCATION': '/tmp/memcached.sock', 14 } 15 } 16 17 CACHES = { 18 'default': { 19 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 20 'LOCATION': [ 21 '172.19.26.240:11211', 22 '172.19.26.242:11211', 23 ] 24 } 25 }
二、應用
a. 全站使用
使用中間件,通過一系列的認證等操做,若是內容在緩存中存在,則使用FetchFromCacheMiddleware獲取內容並返回給用戶,
當返回給用戶以前,判斷緩存中是否已經存在,若是不存在則UpdateCacheMiddleware會將緩存保存至緩存,從而實現全站緩存。
1 MIDDLEWARE = [ 2 'django.middleware.cache.UpdateCacheMiddleware', 3 # 其餘中間件... 4 'django.middleware.cache.FetchFromCacheMiddleware', 5 ] 6 7 CACHE_MIDDLEWARE_ALIAS = "" 8 CACHE_MIDDLEWARE_SECONDS = "" 9 CACHE_MIDDLEWARE_KEY_PREFIX = ""
b. 單獨視圖緩存
方式一: from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ... 方式二: from django.views.decorators.cache import cache_page urlpatterns = [ url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)), ]
c、局部視圖使用
a. 引入TemplateTag {% load cache %} b. 使用緩存 {% cache 5000 緩存key %} 緩存內容 {% endcache %}
關於Django中的序列化主要應用在將數據庫中檢索的數據返回給客戶端用戶,特別的Ajax請求通常返回的爲Json格式。
一、serializers
1 from django.core import serializers 2 3 ret = models.BookType.objects.all() 4 5 data = serializers.serialize("json", ret)
二、json.dumps
1 import json 2 3 #ret = models.BookType.objects.all().values('caption') 4 ret = models.BookType.objects.all().values_list('caption') 5 6 ret=list(ret) 7 8 result = json.dumps(ret)
因爲json.dumps時沒法處理datetime日期,因此能夠經過自定義處理器來作擴展,如:
1 import json 2 from datetime import date 3 from datetime import datetime 4 5 class JsonCustomEncoder(json.JSONEncoder): 6 7 def default(self, field): 8 9 if isinstance(field, datetime): 10 return o.strftime('%Y-%m-%d %H:%M:%S') 11 elif isinstance(field, date): 12 return o.strftime('%Y-%m-%d') 13 else: 14 return json.JSONEncoder.default(self, field) 15 16 17 # ds = json.dumps(d, cls=JsonCustomEncoder)
Django中提供了「信號調度」,用於在框架執行操做時解耦。通俗來說,就是一些動做發生的時候,信號容許特定的發送者去提醒一些接受者。
一、Django內置信號
1 Model signals 2 pre_init # django的modal執行其構造方法前,自動觸發 3 post_init # django的modal執行其構造方法後,自動觸發 4 pre_save # django的modal對象保存前,自動觸發 5 post_save # django的modal對象保存後,自動觸發 6 pre_delete # django的modal對象刪除前,自動觸發 7 post_delete # django的modal對象刪除後,自動觸發 8 m2m_changed # django的modal中使用m2m字段操做第三張表(add,remove,clear)先後,自動觸發 9 class_prepared # 程序啓動時,檢測已註冊的app中modal類,對於每個類,自動觸發 10 Management signals 11 pre_migrate # 執行migrate命令前,自動觸發 12 post_migrate # 執行migrate命令後,自動觸發 13 Request/response signals 14 request_started # 請求到來前,自動觸發 15 request_finished # 請求結束後,自動觸發 16 got_request_exception # 請求異常後,自動觸發 17 Test signals 18 setting_changed # 使用test測試修改配置文件時,自動觸發 19 template_rendered # 使用test測試渲染模板時,自動觸發 20 Database Wrappers 21 connection_created # 建立數據庫鏈接時,自動觸發
對於Django內置的信號,僅需註冊指定信號,當程序執行相應操做時,自動觸發註冊函數:
1 from django.core.signals import request_finished 2 from django.core.signals import request_started 3 from django.core.signals import got_request_exception 4 5 from django.db.models.signals import class_prepared 6 from django.db.models.signals import pre_init, post_init 7 from django.db.models.signals import pre_save, post_save 8 from django.db.models.signals import pre_delete, post_delete 9 from django.db.models.signals import m2m_changed 10 from django.db.models.signals import pre_migrate, post_migrate 11 12 from django.test.signals import setting_changed 13 from django.test.signals import template_rendered 14 15 from django.db.backends.signals import connection_created 16 17 18 def callback(sender, **kwargs): 19 print("xxoo_callback") 20 print(sender,kwargs) 21 22 xxoo.connect(callback) 23 # xxoo指上述導入的內容
1 from django.core.signals import request_finished 2 from django.dispatch import receiver 3 4 @receiver(request_finished) 5 def my_callback(sender, **kwargs): 6 print("Request finished!")
二、自定義信號
a. 定義信號
1 import django.dispatch 2 pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
b. 註冊信號
1 def callback(sender, **kwargs): 2 print("callback") 3 print(sender,kwargs) 4 5 pizza_done.connect(callback)
c. 觸發信號
1 from 路徑 import pizza_done 2 3 pizza_done.send(sender='seven',toppings=123, size=456)
因爲內置信號的觸發者已經集成到Django中,因此其會自動調用,而對於自定義信號則須要開發者在任意位置觸發。
Django的Form主要具備一下幾大功能:
一、建立Form類
1 from django.forms import Form 2 from django.forms import widgets 3 from django.forms import fields 4 5 class MyForm(Form): 6 user = fields.CharField( 7 widget=widgets.TextInput(attrs={'id': 'i1', 'class': 'c1'}) 8 ) 9 10 gender = fields.ChoiceField( 11 choices=((1, '男'), (2, '女'),), 12 initial=2, 13 widget=widgets.RadioSelect 14 ) 15 16 city = fields.CharField( 17 initial=2, 18 widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) 19 ) 20 21 pwd = fields.CharField( 22 widget=widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True) 23 )
二、View函數處理
1 from django.shortcuts import render, redirect 2 from .forms import MyForm 3 4 5 def index(request): 6 if request.method == "GET": 7 obj = MyForm() 8 return render(request, 'index.html', {'form': obj}) 9 elif request.method == "POST": 10 obj = MyForm(request.POST, request.FILES) 11 if obj.is_valid(): 12 values = obj.clean() 13 print(values) 14 else: 15 errors = obj.errors 16 print(errors) 17 return render(request, 'index.html', {'form': obj}) 18 else: 19 return redirect('http://www.google.com')
三、生成HTML
1 <form action="/" method="POST" enctype="multipart/form-data"> 2 <p>{{ form.user }} {{ form.user.errors }}</p> 3 <p>{{ form.gender }} {{ form.gender.errors }}</p> 4 <p>{{ form.city }} {{ form.city.errors }}</p> 5 <p>{{ form.pwd }} {{ form.pwd.errors }}</p> 6 <input type="submit"/> 7 </form>
1 <form method="POST" enctype="multipart/form-data"> 2 {% csrf_token %} 3 4 {{ form.xxoo.label }} 5 {{ form.xxoo.id_for_label }} 6 {{ form.xxoo.label_tag }} 7 {{ form.xxoo.errors }} 8 <p>{{ form.user }} {{ form.user.errors }}</p> 9 <input type="submit" /> 10 </form>
建立Form類時,主要涉及到 【字段】 和 【插件】,字段用於對用戶請求數據的驗證,插件用於自動生成HTML;
一、Django內置字段以下:
Field required=True, 是否容許爲空 widget=None, HTML插件 label=None, 用於生成Label標籤或顯示內容 initial=None, 初始值 help_text='', 幫助信息(在標籤旁邊顯示) error_messages=None, 錯誤信息 {'required': '不能爲空', 'invalid': '格式錯誤'} show_hidden_initial=False, 是否在當前插件後面再加一個隱藏的且具備默認值的插件(可用於檢驗兩次輸入是否一直) validators=[], 自定義驗證規則 localize=False, 是否支持本地化 disabled=False, 是否能夠編輯 label_suffix=None Label內容後綴 CharField(Field) max_length=None, 最大長度 min_length=None, 最小長度 strip=True 是否移除用戶輸入空白 IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 FloatField(IntegerField) ... DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 總長度 decimal_places=None, 小數位長度 BaseTemporalField(Field) input_formats=None 時間格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(Field) 時間間隔:%d %H:%M:%S.%f ... RegexField(CharField) regex, 自定製正則表達式 max_length=None, 最大長度 min_length=None, 最小長度 error_message=None, 忽略,錯誤信息使用 error_messages={'invalid': '...'} EmailField(CharField) ... FileField(Field) allow_empty_file=False 是否容許空文件 ImageField(FileField) ... 注:須要PIL模塊,pip3 install Pillow 以上兩個字典使用時,須要注意兩點: - form表單中 enctype="multipart/form-data" - view函數中 obj = MyForm(request.POST, request.FILES) URLField(Field) ... BooleanField(Field) ... NullBooleanField(BooleanField) ... ChoiceField(Field) ... choices=(), 選項,如:choices = ((0,'上海'),(1,'北京'),) required=True, 是否必填 widget=None, 插件,默認select插件 label=None, Label內容 initial=None, 初始值 help_text='', 幫助提示 ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查詢數據庫中的數據 empty_label="---------", # 默認空顯示內容 to_field_name=None, # HTML中value的值對應的字段 limit_choices_to=None # ModelForm中對queryset二次篩選 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField TypedChoiceField(ChoiceField) coerce = lambda val: val 對選中的值進行一次轉換 empty_value= '' 空值的默認值 MultipleChoiceField(ChoiceField) ... TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 對選中的每個值進行一次轉換 empty_value= '' 空值的默認值 ComboField(Field) fields=() 使用多個驗證,以下:即驗證最大長度20,又驗證郵箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field) PS: 抽象類,子類中能夠實現聚合多個字典去匹配一個值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] FilePathField(ChoiceField) 文件選項,目錄下文件顯示在頁面中 path, 文件夾路徑 match=None, 正則匹配 recursive=False, 遞歸下面的文件夾 allow_files=True, 容許文件 allow_folders=False, 容許文件夾 required=True, widget=None, label=None, initial=None, help_text='' GenericIPAddressField protocol='both', both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,若是是::ffff:192.0.2.1時候,可解析爲192.0.2.1, PS:protocol必須爲both才能啓用 SlugField(CharField) 數字,字母,下劃線,減號(連字符) ... UUIDField(CharField) uuid類型 ...
注:UUID是根據MAC以及當前時間等建立的不重複的隨機字符串
1 >>> import uuid 2 3 # make a UUID based on the host ID and current time 4 >>> uuid.uuid1() # doctest: +SKIP 5 UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') 6 7 # make a UUID using an MD5 hash of a namespace UUID and a name 8 >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org') 9 UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') 10 11 # make a random UUID 12 >>> uuid.uuid4() # doctest: +SKIP 13 UUID('16fd2706-8baf-433b-82eb-8c7fada847da') 14 15 # make a UUID using a SHA-1 hash of a namespace UUID and a name 16 >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org') 17 UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d') 18 19 # make a UUID from a string of hex digits (braces and hyphens ignored) 20 >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}') 21 22 # convert a UUID to a string of hex digits in standard form 23 >>> str(x) 24 '00010203-0405-0607-0809-0a0b0c0d0e0f' 25 26 # get the raw 16 bytes of the UUID 27 >>> x.bytes 28 b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' 29 30 # make a UUID from a 16-byte string 31 >>> uuid.UUID(bytes=x.bytes) 32 UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
二、Django內置插件:
TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget
經常使用選擇插件
# 單radio,值爲字符串 # user = fields.CharField( # initial=2, # widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),)) # ) # 單radio,值爲字符串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.RadioSelect # ) # 單select,值爲字符串 # user = fields.CharField( # initial=2, # widget=widgets.Select(choices=((1,'上海'),(2,'北京'),)) # ) # 單select,值爲字符串 # user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), # initial=2, # widget=widgets.Select # ) # 多選select,值爲列表 # user = fields.MultipleChoiceField( # choices=((1,'上海'),(2,'北京'),), # initial=[1,], # widget=widgets.SelectMultiple # ) # 單checkbox # user = fields.CharField( # widget=widgets.CheckboxInput() # ) # 多選checkbox,值爲列表 # user = fields.MultipleChoiceField( # initial=[2, ], # choices=((1, '上海'), (2, '北京'),), # widget=widgets.CheckboxSelectMultiple # )
在使用選擇標籤時,須要注意choices的選項能夠從數據庫中獲取,可是因爲是靜態字段 ***獲取的值沒法實時更新***,那麼須要自定義構造方法從而達到此目的。
方式一:
1 from django.forms import Form 2 from django.forms import widgets 3 from django.forms import fields 4 from django.core.validators import RegexValidator 5 6 class MyForm(Form): 7 8 user = fields.ChoiceField( 9 # choices=((1, '上海'), (2, '北京'),), 10 initial=2, 11 widget=widgets.Select 12 ) 13 14 def __init__(self, *args, **kwargs): 15 super(MyForm,self).__init__(*args, **kwargs) 16 # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),) 17 # 或 18 self.fields['user'].widget.choices = models.Classes.objects.all().value_list('id','caption')
方式二:
使用django提供的ModelChoiceField和ModelMultipleChoiceField字段來實現
1 from django import forms 2 from django.forms import fields 3 from django.forms import widgets 4 from django.forms import models as form_model 5 from django.core.exceptions import ValidationError 6 from django.core.validators import RegexValidator 7 8 class FInfo(forms.Form): 9 authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) 10 # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
方式一:
1 from django.forms import Form 2 from django.forms import widgets 3 from django.forms import fields 4 from django.core.validators import RegexValidator 5 6 class MyForm(Form): 7 user = fields.CharField( 8 validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')], 9 )
方式二:
1 import re 2 from django.forms import Form 3 from django.forms import widgets 4 from django.forms import fields 5 from django.core.exceptions import ValidationError 6 7 8 # 自定義驗證規則 9 def mobile_validate(value): 10 mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') 11 if not mobile_re.match(value): 12 raise ValidationError('手機號碼格式錯誤') 13 14 15 class PublishForm(Form): 16 17 18 title = fields.CharField(max_length=20, 19 min_length=5, 20 error_messages={'required': '標題不能爲空', 21 'min_length': '標題最少爲5個字符', 22 'max_length': '標題最多爲20個字符'}, 23 widget=widgets.TextInput(attrs={'class': "form-control", 24 'placeholder': '標題5-20個字符'})) 25 26 27 # 使用自定義驗證規則 28 phone = fields.CharField(validators=[mobile_validate, ], 29 error_messages={'required': '手機不能爲空'}, 30 widget=widgets.TextInput(attrs={'class': "form-control", 31 'placeholder': u'手機號碼'})) 32 33 email = fields.EmailField(required=False, 34 error_messages={'required': u'郵箱不能爲空','invalid': u'郵箱格式錯誤'}, 35 widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
方法三:自定義方法
1 from django import forms 2 from django.forms import fields 3 from django.forms import widgets 4 from django.core.exceptions import ValidationError 5 from django.core.validators import RegexValidator 6 7 class FInfo(forms.Form): 8 username = fields.CharField(max_length=5, 9 validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.', 'invalid')], ) 10 email = fields.EmailField() 11 12 def clean_username(self): 13 """ 14 Form中字段中定義的格式匹配完以後,執行此方法進行驗證 15 :return: 16 """ 17 value = self.cleaned_data['username'] 18 if "666" in value: 19 raise ValidationError('666已經被玩爛了...', 'invalid') 20 return value
方式四:同時生成多個標籤進行驗證
1 from django.forms import Form 2 from django.forms import widgets 3 from django.forms import fields 4 5 from django.core.validators import RegexValidator 6 7 8 ############## 自定義字段 ############## 9 class PhoneField(fields.MultiValueField): 10 def __init__(self, *args, **kwargs): 11 # Define one message for all fields. 12 error_messages = { 13 'incomplete': 'Enter a country calling code and a phone number.', 14 } 15 # Or define a different message for each field. 16 f = ( 17 fields.CharField( 18 error_messages={'incomplete': 'Enter a country calling code.'}, 19 validators=[ 20 RegexValidator(r'^[0-9]+$', 'Enter a valid country calling code.'), 21 ], 22 ), 23 fields.CharField( 24 error_messages={'incomplete': 'Enter a phone number.'}, 25 validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid phone number.')], 26 ), 27 fields.CharField( 28 validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.')], 29 required=False, 30 ), 31 ) 32 super(PhoneField, self).__init__(error_messages=error_messages, fields=f, require_all_fields=False, *args, 33 **kwargs) 34 35 def compress(self, data_list): 36 """ 37 當用戶驗證都經過後,該值返回給用戶 38 :param data_list: 39 :return: 40 """ 41 return data_list 42 43 ############## 自定義插件 ############## 44 class SplitPhoneWidget(widgets.MultiWidget): 45 def __init__(self): 46 ws = ( 47 widgets.TextInput(), 48 widgets.TextInput(), 49 widgets.TextInput(), 50 ) 51 super(SplitPhoneWidget, self).__init__(ws) 52 53 def decompress(self, value): 54 """ 55 處理初始值,當初始值initial不是列表時,調用該方法 56 :param value: 57 :return: 58 """ 59 if value: 60 return value.split(',') 61 return [None, None, None]
在Web應用程序中開發編寫功能時,時經常使用到獲取數據庫中的數據並將值初始化在HTML中的標籤上。
一、Form
1 from django.forms import Form 2 from django.forms import widgets 3 from django.forms import fields 4 from django.core.validators import RegexValidator 5 6 7 class MyForm(Form): 8 user = fields.CharField() 9 10 city = fields.ChoiceField( 11 choices=((1, '上海'), (2, '北京'),), 12 widget=widgets.Select 13 )
二、Views
1 from django.shortcuts import render, redirect 2 from .forms import MyForm 3 4 5 def index(request): 6 if request.method == "GET": 7 values = {'user': 'root', 'city': 2} 8 obj = MyForm(values) 9 10 return render(request, 'index.html', {'form': obj}) 11 elif request.method == "POST": 12 return redirect('http://www.google.com') 13 else: 14 return redirect('http://www.google.com')
三、HTML
1 <form method="POST" enctype="multipart/form-data"> 2 {% csrf_token %} 3 <p>{{ form.user }} {{ form.user.errors }}</p> 4 <p>{{ form.city }} {{ form.city.errors }}</p> 5 6 <input type="submit"/> 7 </form>
擴展:ModelForm
在使用Model和Form時,都須要對字段進行定義並指定類型,經過ModelForm則能夠省去From中字段的定義
1 class AdminModelForm(forms.ModelForm): 2 3 class Meta: 4 model = models.Admin 5 #fields = '__all__' 6 fields = ('username', 'email') 7 8 widgets = { 9 'email' : forms.PasswordInput(attrs={'class':"alex"}), 10 }