1、路由系統 2、模板引擎 simple_tag 3、Form 4、Ajax請求 -簡單數據 -複雜數據 內容: -做業 model xss、csrf(安全方面的內容) 分頁(公共的模塊)
Django靜態文件引用優化
存在兩種引用方式:
一、方式1
二、方式2html
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, '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', 'django.core.context_processors.static', #新增的內容 ], }, }, ] STATIC_URL = '/static/'
爲何?python
def static(request): """ Adds static-related context variables to the context. """ return {'STATIC_URL': settings.STATIC_URL}
對於views文件和templates來說,在涉及較大量的時候,都應該進行分類處理,好比views\account.py類處理登陸的函數,templates\account下的html文件爲登陸相關的html文件,以下jquery
from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include("app01.urls")), ]
from django.conf.urls import url,include from django.contrib import admin from app01.views import account urlpatterns = [ url(r'^login/', account.login), ]
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render def login(request): return render(request, "account/login.html")
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>abcd</h1> <h1>{{ STATIC_URL }}</h1> <script src="/static/js/jquery-2.1.4.min.js"></script> <script src="{{ STATIC_URL }}js/jquery-2.1.4.min.js"></script> <script src="{% static "js/jquery-2.1.4.min.js"%}"></script> </body> </html>
Form基本功能應用之保存用戶輸入內容git
一、對於不一樣的函數使用的form,應該進行分類:ajax
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django import forms class LoginForm(forms.Form): username = forms.CharField() #字符串 password = forms.CharField(widget=forms.PasswordInput) #沒有字符串的設定格式,經過widget進行設置
二、普通render方式以下,沒法保存用戶輸入內容正則表達式
點擊submit以後,若是用戶密碼或用戶名輸入錯誤,密碼和用戶名輸入框就會都變爲空;sql
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render from app01.forms import account as AccountForm def login(request): ''' if request.method == "POST": inp_obj = AccountForm.LoginForm(request.POST) #封裝了數據的對象,不只能夠作數據的驗證,還能夠將提交的數據再次顯示到頁面上去; return render(request, "account/login.html",{'obj':inp_obj})''' obj = AccountForm.LoginForm() return render(request, "account/login.html",{'obj':obj}) #沒有封裝數據的對象
採用以下方式,會保存用戶名:數據庫
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render from app01.forms import account as AccountForm #爲了區分views的account,使用as def login(request): '''一、第一次登錄爲get,不會執行if部分''' if request.method == "POST": inp_obj = AccountForm.LoginForm(request.POST) #封裝了數據的對象,不只能夠作數據的驗證,還能夠將提交的數據再次顯示到頁面上去; return render(request, "account/login.html",{'obj':inp_obj}) obj = AccountForm.LoginForm() return render(request, "account/login.html",{'obj':obj}) #沒有封裝數據的對象
或者:django
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render from app01.forms import account as AccountForm #爲了區分views的account,使用as def login(request): obj = AccountForm.LoginForm(request.POST) #獲取頁面輸入的數據 if request.method == "POST": return render(request, "account/login.html",{'obj':obj}) return render(request, "account/login.html",{'obj':obj})
Form基本功能應用之驗證以及錯誤信息json
下面利用form對於post提交的數據進行驗證
對於error信息,有三種輸出形式:
一、as_ul
二、as_data:用於form,和不用as_data相同;
三、as_json:用於Ajax;
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render,HttpResponse from app01.forms import account as AccountForm #爲了區分views的account,使用as def login(request): obj = AccountForm.LoginForm(request.POST) #獲取頁面輸入的數據 if request.method == "POST": if obj.is_valid(): all_data = obj.clean() else: #Form表單提交 error = obj.errors print type(error) print error['username'],type(error['username']) print error['username'][0],type(error['username'][0]) print error['username'][0] print error['password'][0] ''' 1、as_ul 2、as_data 3、as_json ''' #Ajax #error = obj.errors.as_json() #return HttpResponse(error) #print error,type(error) return render(request, "account/login.html",{'obj':obj,'error':error}) return render(request, "account/login.html",{'obj':obj}) #form返回obj對象 #若是是ajax的話,return HttpReponse("字符串或者字符串類型的字典,不能爲obj對象")
{% load staticfiles %} {% load xx %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="post"> <p>{{ obj.username }} <span style="color: red;">{% error_msg error.username %}</span> #由於模板語言不支持obj.username[0]的方式取第一個錯誤信息,因此經過simple_tag來實現 </p> <p>{{ obj.password }}</p> <input type="submit" value="submit" /> </form> <h1>abcd</h1> <script src="/static/js/jquery-2.1.4.min.js"></script> <script src="{% static "js/jquery-2.1.4.min.js"%}"></script> <script> </script> </body> </html>
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django import template from django.utils.safestring import mark_safe from django.template.base import resolve_variable, Node, TemplateSyntaxError register = template.Library() @register.simple_tag def error_msg(error_list): if error_list: return error_list[0] return ""
下面利用Ajax推數據進行提交:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render,HttpResponse from app01.forms import account as AccountForm #爲了區分views的account,使用as def login(request): obj = AccountForm.LoginForm(request.POST) #獲取頁面輸入的數據 if request.method == "POST": if obj.is_valid(): all_data = obj.clean() else: #Form表單提交 error = obj.errors print type(error) #print error['username'],type(error['username']) #print error['username'][0],type(error['username'][0]) #print error['username'][0] #print error['password'][0] ''' 1、as_ul 2、as_data 3、as_json ''' #Ajax error = obj.errors.as_json() return HttpResponse(error) print error,type(error) return render(request, "account/login.html",{'obj':obj,'error':error}) return render(request, "account/login.html",{'obj':obj}) #form返回obj對象 #若是是ajax的話,return HttpReponse("字符串或者字符串類型的字典,不能爲obj對象")
{% load staticfiles %} {% load xx %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="post"> <p>{{ obj.username }} <span style="color: red;">{% error_msg error.username %}</span> </p> <p>{{ obj.password }}</p> <input type="submit" value="submit" /> <input type="button" onclick="SubmitAjax();" value="Ajax" /> </form> <h1>abcd</h1> <script src="/static/js/jquery-2.1.4.min.js"></script> <script src="{% static "js/jquery-2.1.4.min.js"%}"></script> <script> function SubmitAjax(){ $.ajax({ 'url':'/login/', type:'POST', data: {'username':'','password':''}, success:function(arg){ console.log(arg); } }) } </script> </body> </html>
Form功能應用之自動生成select標籤
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render from app01.forms import home as HomeForm def index(request): obj = HomeForm.ImportForm() return render(request,'home/index.html',{'obj':obj})
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django import forms class ImportForm(forms.Form): HOST_TYPE_LIST = ( (1,'物理機'), (2,'虛擬機') ) host_type = forms.IntegerField( widget=forms.Select(choices=HOST_TYPE_LIST) ) hostname = forms.CharField() import json ''' f = open('db_admin','w') dic = ((1,"Charles"),(2,"wahaha")) f.write(json.dumps(dic)) f.close() ''' fr = open('db_admin') data = fr.read() print data,type(data) data_tuple = json.loads(data) fr.close() admin = forms.IntegerField( widget=forms.Select(choices=data_tuple) ) '''若是沒有下面的構造方法,在配置文件db_admin內容修改以後,select下面選擇的內容不會改變; 緣由是根據類的定義,其靜態字段在程序啓動的時候會在內存中加載一次以後不會再改變,除非類從新加載(程序重啓) 由於靜態字段是存在於類中的,而對於self.的方法,其存在於對象中,在對象被從新賦值的時候,值會改變,這樣能夠在刷新頁面的 時候,select下面的選擇內容會改變''' def __init__(self, *args, **kwargs): super(ImportForm, self).__init__(*args, **kwargs) fr = open('db_admin') import json data = fr.read() print data,type(data) data_tuple = json.loads(data) fr.close() self.fields['admin'].widget.choices = data_tuple
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>錄入數據</h1> <form action="/index/"> <p>{{ obj.host_type }}</p> <p>{{ obj.hostname }}</p> <p>{{ obj.admin }}</p> </form> <h1>數據列表</h1> </body> </html>
[[1, "Charles"], [2, "www"],[3,"ddddd"],[4,"gggggg"]]
Form功能之生成動態select標籤
上述代碼能夠進行優化:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django import forms class ImportForm(forms.Form): HOST_TYPE_LIST = ( (1,'物理機'), (2,'虛擬機') ) host_type = forms.IntegerField( widget=forms.Select(choices=HOST_TYPE_LIST) ) hostname = forms.CharField() admin = forms.IntegerField( widget=forms.Select() #獲取空值,在下面執行__init__方法的時候從新賦值 ) '''若是沒有下面的構造方法,在配置文件db_admin內容修改以後,select下面選擇的內容不會改變; 緣由是根據類的定義,其靜態字段在程序啓動的時候會在內存中加載一次以後不會再改變,除非類從新加載(程序重啓) 由於靜態字段是存在於類中的,而對於self.的方法,其存在於對象中,在對象被從新賦值的時候,值會改變,這樣能夠在刷新頁面的 時候,select下面的選擇內容會改變''' def __init__(self, *args, **kwargs): super(ImportForm, self).__init__(*args, **kwargs) fr = open('db_admin') #在使用models的時候,可使用數據庫獲取數據 import json data = fr.read() print data,type(data) data_tuple = json.loads(data) fr.close() self.fields['admin'].widget.choices = data_tuple
Model建立表之基礎字段:
model中的數據庫的錯作爲ORM;數據庫經過model中的類表示,對象爲其中的一行數據,對象.id ,對象.value爲每行裏面的數據;
其中settings中配置數據庫:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
#!/usr/bin/env python #coding:utf-8 from __future__ import unicode_literals from django.db import models # Create your models here. #ORM #類-->數據庫 #對象-->一行數據 #對象.id 對象.value -->每行裏面的數據 class UserInfo(models.Model): #默認狀況下,表會生成兩列 name = models.CharField(max_length=32) ctime = models.DateTimeField(auto_now=True) #建立時間字段,數據爲當前時間 uptime = models.DateTimeField(auto_now_add=True) #更新數據,日期自動添加 email1 = models.EmailField(max_length=32,null=True) #表中添加一列,數據爲null email2 = models.EmailField(max_length=32,default='123@123.com') #表中添加一列,數據爲'123@123.com' def __unicode__(self): #輸出對象的時候,輸出數據庫中一行數據爲name的一列 return self.name
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render from app01.forms import home as HomeForm from app01 import models def index(request): models.UserInfo.objects.all().delete() #刪除數據 before = models.UserInfo.objects.all() #獲取全部數據 models.UserInfo.objects.create(name = 'Charles') #添加數據 after = models.UserInfo.objects.all() print before print after print after[0].ctime obj = HomeForm.ImportForm() return render(request,'home/index.html',{'obj':obj})
python manage.py syncdb命令同步數據庫表,須要事先將app註冊到settings中;
#!/usr/bin/env python #coding:utf-8 from __future__ import unicode_literals from django.db import models # Create your models here. #ORM #類-->數據庫 #對象-->一行數據 #對象.id 對象.value -->每行裏面的數據 class UserInfo(models.Model): #默認狀況下,表會生成兩列 name = models.CharField(max_length=32) ctime = models.DateTimeField(auto_now=True) #建立時間字段,數據爲當前時間 uptime = models.DateTimeField(auto_now_add=True) #更新數據,日期自動添加 email1 = models.EmailField(max_length=32,null=True) #表中添加一列,數據爲null email2 = models.EmailField(max_length=32,default='123@123.com') #表中添加一列,數據爲'123@123.com' ip=models.GenericIPAddressField(protocol="ipv4") img = models.ImageField(null=True,blank=True,upload_to="upload") #blank=True表示在admin後臺管理的時候容許爲空 upload_to表示圖片上傳的路徑,默認會自動建立 def __unicode__(self): #輸出對象的時候,輸出數據庫中一行數據爲name的一列 return self.name
經過admin來管理數據庫表:
from django.contrib import admin # Register your models here. from app01 import models admin.site.register(models.UserInfo)
Model建立表之字段參數:
1、models.AutoField 自增列 = int(11) 若是沒有的話,默認會生成一個名稱爲 id 的列,若是要顯示的自定義一個自增列,必須將給列設置爲主鍵 primary_key=True。 2、models.CharField 字符串字段 必須 max_length 參數 3、models.BooleanField 布爾類型=tinyint(1) 不能爲空,Blank=True 4、models.ComaSeparatedIntegerField 用逗號分割的數字=varchar 繼承CharField,因此必須 max_lenght 參數 5、models.DateField 日期類型 date 對於參數,auto_now = True 則每次更新都會更新這個時間;auto_now_add 則只是第一次建立添加,以後的更新再也不改變。 6、models.DateTimeField 日期類型 datetime 同DateField的參數 7、models.Decimal 十進制小數類型 = decimal 必須指定整數位max_digits和小數位decimal_places 8、models.EmailField 字符串類型(正則表達式郵箱) =varchar 對字符串進行正則表達式 9、models.FloatField 浮點類型 = double 10、models.IntegerField 整形 11、models.BigIntegerField 長整形 integer_field_ranges = { 'SmallIntegerField': (-32768, 32767), 'IntegerField': (-2147483648, 2147483647), 'BigIntegerField': (-9223372036854775808, 9223372036854775807), 'PositiveSmallIntegerField': (0, 32767), 'PositiveIntegerField': (0, 2147483647), } 12、models.IPAddressField 字符串類型(ip4正則表達式) 13、models.GenericIPAddressField 字符串類型(ip4和ip6是可選的) 參數protocol能夠是:both、ipv四、ipv6 驗證時,會根據設置報錯 14、models.NullBooleanField 容許爲空的布爾類型 15、models.PositiveIntegerFiel 正Integer 16、models.PositiveSmallIntegerField 正smallInteger 17、models.SlugField 減號、下劃線、字母、數字 18、models.SmallIntegerField 數字 數據庫中的字段有:tinyint、smallint、int、bigint 19、models.TextField 字符串=longtext 20、models.TimeField 時間 HH:MM[:ss[.uuuuuu]] 21、models.URLField 字符串,地址正則表達式 22、models.BinaryField 二進制 23、models.ImageField 圖片 24、models.FilePathField 文件 更多字段
AutoField()
BooleanField()
CharField()
CommaSeparatedIntegerField()
DateField()
DateTimeField()
DecimalField()
EmailField()
FilePathField()
FloatField()
IntegerField()
BinIntegerField()
IPAddressField()
TextField()
TimeField()
URLField()
BinaryField()
下面介紹經過Django上傳文件示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/upload/" method="POST" enctype="multipart/form-data"> //enctype="multipart/form-data"表示多個文件上傳 <p><input type="file" name="f1"/></p> <p><input type="file" name="f2"/></p> <p><input type="text" name="hostname"/></p> <input type="submit" value="upload"/> </form> </body> </html>
def upload(request): if request.method=='POST': inp_post = request.POST #獲取全部的text文本信息 inp_files=request.FILES #獲取全部的上傳的文件信息 file_obj1 = inp_files.get('f1') print file_obj1.name,type(file_obj1) #獲取上傳文件的文件名 print '333333333' print inp_post f = open(file_obj1.name,'wb') for line in file_obj1.chunks(): #chunks表示將文件進行切片,而後寫入經過內存寫入文件 f.write(line) f.close() return render(request,'home/upload.html')
Model建立表之一對多:外鍵,讓兩張表創建關係;
#!/usr/bin/env python #coding:utf-8 from __future__ import unicode_literals from django.db import models # Create your models here. #ORM #類-->數據庫 #對象-->一行數據 #對象.id 對象.value -->每行裏面的數據 class UserInfo(models.Model): #默認狀況下,表會生成兩列 USER_TYPE_LIST=( (1,'f'), (2,'m'), ) user_type = models.IntegerField(choices=USER_TYPE_LIST,default=1) name = models.CharField(max_length=32,primary_key=True,verbose_name="姓名",unique=True) ctime = models.DateTimeField(auto_now=True,) #建立時間字段,數據爲當前時間 uptime = models.DateTimeField(auto_now_add=True,db_column="SB") #更新數據,日期自動添加 email1 = models.EmailField(max_length=32,null=True) #表中添加一列,數據爲null email2 = models.EmailField(max_length=32,default='123@123.com') #表中添加一列,數據爲'123@123.com' ip=models.GenericIPAddressField(protocol="ipv4") img = models.ImageField(null=True,blank=True,upload_to="upload") #blank=True表示在admin後臺管理的時候容許爲空 def __unicode__(self): #輸出對象的時候,輸出數據庫中一行數據爲name的一列 return self.name class Color(models.Model): name = models.CharField(max_length=16) class Somthing(models.Model): c1 = models.CharField(max_length=10) c2 = models.CharField(max_length=10) c3 = models.CharField(max_length=10) c4 = models.CharField(max_length=10) color = models.ForeignKey(Color) #將兩張表經過外鍵進行關聯 class Business(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=16) class Host(models.Model): hostname = models.CharField(max_length=16) business = models.ForeignKey('Business',to_field='nid') #指定app01business表的nid列爲外鍵
>python manage.py makemigrations
python manage.py migrate
更新表結構;
Model建立表之多對多:一我的能夠屬於多個組,一個組能夠包含多我的;
須要建立第三張表,關聯用戶ID和組ID;
class UserGroup(models.Model): group_name = models.CharField(max_length=16) class User(models.Model): name = models.CharField(max_length=16) email = models.CharField(max_length=16) mobile = models.CharField(max_length=16) user_user_group= models.ManyToManyField('UserGroup') #建立的第三張表,將UserGroup表id和User表的id進行關聯
Model建立表之一對一:實際在數據庫表建立的時候不存在;同一張表的同一列不能有重複的數據,不然不能insert進去;就是在一對多的基礎上加上了不能重複的要求;
好比用戶名:密碼:id等不能重複;
class User2(models.Model): name = models.CharField(max_length=16) email = models.CharField(max_length=16) mobile = models.CharField(max_length=16) class AAdmin(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=16) user_info = models.OneToOneField('User2') #一對一兩張表關聯
Model操做表之基礎操做
增:
model.Tb1.objects.create(c1='xx',c2='oo') 或者 obj = model.Tb1(c1='xx',c2='oo') obj.save() 或者 dic = {'c1':'xx','c2':'oo'} #能夠將form提交的數據傳入 model.Tb1.objects.create(**dic)
查:
model.Tb1.objects.get(id=123) #獲取一行,若是不存在,拋異常 model.Tb1.objects.all() #獲取所有 model.Tb1.objects.filter(name='seven','gender':'0') #獲取數據,能夠用**dic替代括號中的內容 model.Tb1.objects.all().first() #獲取第一條數據
刪:
model.Tb1.objects.filter(name='seven').delete()
改:
model.Tb1.objects.filter(name='seven').update(gender='0') #括號中的內容均可以經過**dic來替代 或者: obj=model.Tb1.objects.get(id=1) #獲取對象 obj.c1='111' obj.save()
好了,上面是關於表操做的基礎部分,下面開始介紹如何在實際中操做:
一、建立表SimpleModel
class SimpleModel(models.Model): username = models.CharField(max_length=64) password = models.CharField(max_length=64)
二、表數據的增長和查詢:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import render from app01.forms import home as HomeForm from app01 import models def index(request): dic = {'username':'QQ','password':'123'} models.SimpleModel.objects.create(**dic) ret = models.SimpleModel.objects.all() print ret,type(ret),ret.query ret = models.SimpleModel.objects.all().values('username') print ret,type(ret) ret = models.SimpleModel.objects.all().values_list('username') print ret,type(ret) ret = models.SimpleModel.objects.all().values_list('id','username') print ret,type(ret) obj = HomeForm.ImportForm() return render(request,'home/index.html',{'obj':obj})
三、替代以前將select的內容寫入配置文件中的方式,採用數據庫的方式:app01/forms/home.py
from django import forms from app01 import models class ImportForm(forms.Form): HOST_TYPE_LIST = ( (1,'物理機'), (2,'虛擬機') ) host_type = forms.IntegerField( widget=forms.Select(choices=HOST_TYPE_LIST) ) hostname = forms.CharField() admin = forms.IntegerField( widget=forms.Select() #獲取空值,在下面執行__init__方法的時候從新賦值 ) '''若是沒有下面的構造方法,在配置文件db_admin內容修改以後,select下面選擇的內容不會改變; 緣由是根據類的定義,其靜態字段在程序啓動的時候會在內存中加載一次以後不會再改變,除非類從新加載(程序重啓) 由於靜態字段是存在於類中的,而對於self.的方法,其存在於對象中,在對象被從新賦值的時候,值會改變,這樣能夠在刷新頁面的 時候,select下面的選擇內容會改變''' def __init__(self, *args, **kwargs): super(ImportForm, self).__init__(*args, **kwargs) self.fields['admin'].widget.choices = models.SimpleModel.objects.all().values_list('id','username') ''' fr = open('db_admin') #在使用models的時候,可使用數據庫獲取數據 import json data = fr.read() print data,type(data) data_tuple = json.loads(data) fr.close() self.fields['admin'].widget.choices = data_tuple
四、將該數據庫能夠經過admin後臺進行管理:
from django.contrib import admin # Register your models here. from app01 import models admin.site.register(models.UserInfo) admin.site.register(models.SimpleModel)
Admin定製:
class School(models.Model): name = models.CharField(max_length=128,unique=True) city = models.CharField(max_length=64) addr = models.CharField(max_length=128) def __unicode__(self): return self.name class UserProfile(models.Model): user = models.OneToOneField(User) #alex name = models.CharField(max_length=64) school = models.ForeignKey('School') class ClassList(models.Model): course = models.ForeignKey(Course,verbose_name=u"課程") semester = models.IntegerField(verbose_name=u"學期") course_type = models.CharField(max_length=64,choices=course_type_choices,default='offline_weekend') teachers = models.ManyToManyField(UserProfile) start_date = models.DateField() graduate_date = models.DateField()
定製代碼以下:
from django.contrib import admin import models # Register your models here. class UserProfileAdmin(admin.ModelAdmin): list_display = ('id','user','name','school') #定義要顯示的字段,不能是多對多的字段 search_fields = ('name','school__name') #能夠被搜索的字典,若是是經過外鍵關聯,使用__表示 list_filter = ('name','school__name') #定義右側經過哪些字段過濾出來的內容 list_editable = ('name','user','school') #定義哪些字段能夠直接被編輯的 list_per_page = 10 #定義每頁顯示幾行數據 raw_id_fields = ('user','school') #若是是經過外鍵關聯的字段,可能存在許多選擇的內容,優化選擇 class ClassListAdmin(admin.ModelAdmin): list_display = ('course','semester','course_type','start_date','graduate_date') filter_horizontal = ('teachers',) #多對多的字段,顯示更加明顯 admin.site.register(models.UserProfile,UserProfileAdmin) admin.site.register(models.Customer) admin.site.register(models.CustomerTrackRecord) admin.site.register(models.ClassList,ClassListAdmin) admin.site.register(models.Course) admin.site.register(models.CourseRecord) admin.site.register(models.StudyRecord) admin.site.register(models.School)
還有xadmin能夠定製化漂亮的admin展現,有興趣能夠本身查!!
默認的admin action只要批量選擇刪除的功能,action只有在批量的時候纔會有用;
def changeschool(modelAdmin,request,queryset): print '--->',request,queryset queryset.update(school=2) changeschool.short_description=u'set 2' def changeschool1(modelAdmin,request,queryset): print '--->',request,queryset queryset.update(school=1) changeschool1.short_description=u'set 1' class UserProfileAdmin(admin.ModelAdmin): list_display = ('id','user','name','school') search_fields = ('name','school__name') list_filter = ('name','school__name') list_editable = ('name','user','school') list_per_page = 10 raw_id_fields = ('user','school') actions = [changeschool,changeschool1,]
Admin定製之加顏色
首先在model中定義方法:
class Customer(models.Model): qq = models.CharField(max_length=64,unique=True) name = models.CharField(verbose_name=u"姓名",max_length=32,blank=True,null=True) phone = models.BigIntegerField(blank=True,null=True) course = models.ForeignKey('Course') course_type = models.CharField(max_length=64,choices=course_type_choices,default='offline_weekend') consult_memo = models.TextField() source_type_choices = (('qq',u"qq羣"), ('referral',u"內部轉介紹"), ('51cto',u"51cto"), ('agent',u"招生代理"), ('others',u"其它"), ) source_type = models.CharField(max_length=64,choices=source_type_choices) def choice_source(self): if self.source_type == 'qq': format_td = format_html('<span style="padding:2px;background-color:pink;color:white"> %s</span>' %self.source_type) elif self.source_type == 'referral': format_td = format_html('<span style="padding:2px;background-color:pink;color:white"> %s</span>'%self.source_type) else: format_td = format_html('<span style="padding:2px;background-color:pink;color:blank"> %s</span>' %self.source_type) return format_td choice_source.short_description='source_type' #修改admin顯示的字段
將定義的函數註冊到Admin中:
class CustomerAdmin(admin.ModelAdmin): list_display = ('source_type','choice_source')
效果以下:
Model操做表之進階操做:
獲取個數: models.Tb1.objects.filter(name='seven').count() 大於,小於 models.Tb1.objects.filter(id__gt=1) models.Tb1.objects.filter(id__lt=1) models.Tb1.objects.filter(id__lt=10,id_gt=1) in models.Tb1.objects.flter(id__in=[11,22,33]) models.Tb1.objects.exclude(id__in=[11,22,33]) contains 相似於like models.Tb1.objects.filter(name__contains="ven") models.Tb1.objects.filter(name__icontains="ven") #icontains大小寫不敏感 models.Tb1.objects.exclude(name__icontains="ven") range 範圍 models.Tb1.objects.filter(id__range=[1,2]) #between and 其餘相似: startwith,istartwith,endswith,iendswith order by models.Tb1.objects.filter(name='seven').order_by('id') #asc models.Tb1.objects.filter(name='seven').order_by('-id') #desc limit、offset models.Tb1.objects.all()[10:20] group by from django.db.models import Count,Min,Max,Sum models.Tb1.objects.filter(c1=1).values(id).annotate(c=Count('num')) models.Tb1.objects.all().values(id).annotate(c=Count('num')) #以id進行分組,並計算相同組的num的最大值、最小值、和、個數等;
連表操做(數據庫數據插入和數據查詢展現),一對多操做
一、建立用戶組表和用戶組表,並經過外鍵進行關聯
class UserGroup_NEW(models.Model): caption = models.CharField(max_length=64) def __unicode__(self): return self.caption class User_NEW(models.Model): username = models.CharField(max_length=64) user_group = models.ForeignKey('UserGroup_NEW') #默認建立的外鍵會加上_id,可使用db_clomn來修改成自定義的列名 def __unicode__(self): return self.username
二、form
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django import forms from app01 import models class UserForm(forms.Form): username = forms.CharField() user_group_id = forms.IntegerField( #採用方式2直接插入數據的話,須要加_id widget=forms.Select() #獲取空值,在下面執行__init__方法的時候從新賦值 ) def __init__(self, *args, **kwargs): super(UserForm, self).__init__(*args, **kwargs) self.fields['user_group_id'].widget.choices = models.UserGroup_NEW.objects.all().values_list('id','caption')
三、數據插入方式有兩種:a、經過對象插入;b、直接插入;
#!/usr/bin/env python # _*_ coding:utf-8 _*_ from django.shortcuts import HttpResponse,render from app01 import models from app01.forms import foreign as ForgienForm def create_user_group(request): # models.UserGroup_NEW.objects.create(caption='CEO') #向用戶組中添加數據 # models.UserGroup_NEW.objects.create(caption='CTO') # models.UserGroup_NEW.objects.create(caption='COO') return HttpResponse('ok') def create_user(request): obj = ForgienForm.UserForm(request.POST) if request.method =="POST": print "數據提交" #print request.POST if obj.is_valid(): all_data = obj.clean() print all_data #獲取對象 # group_obj = models.UserGroup_NEW.objects.get(all_data['use_group']) 方式1 經過對象級別插入數據,group_obj表明對象,是一列數據 # models.User_NEW.objects.create(hostname=all_data['username'], # user_group=group_obj) # models.User_NEW.objects.create(hostname=all_data['username'], # user_group_id=all_data['user_group']) #方式2:能夠經過兩種方式插入數據,默認在Django中插入外鍵會加_id, #此種方法能夠直接插入數據 models.User_NEW.objects.create(**all_data) #將方式2直接修改成此種方式建立數據 print models.User_NEW.objects.all().count() else: pass user_list = models.User_NEW.objects.all() #數據查詢 print user_list return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
四、html模板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/create_user/" method="post"> <p>{{ obj.username }}</p> <p>{{ obj.user_group_id }}</p> <input type="submit" value="submit"/> </form> <table> {% for item in user_list %} <tr> <td>{{ item.username }}</td> <td>{{ item.user_group.caption }}</td> {# 由於在model中的外鍵等一對多的操做,表示對象(就是一行數據),而後取一行數據的單獨一列#} </tr> {% endfor %} </table> </body> </html>
[<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>] [26/Jun/2016 17:40:50] "GET /create_user/ HTTP/1.1" 200 894 數據提交 {'username': u'wahaha', 'user_group_id': 1} 5 [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>] [26/Jun/2016 17:41:03] "POST /create_user/ HTTP/1.1" 200 1023 [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>] [26/Jun/2016 17:46:27] "GET /create_user/ HTTP/1.1" 200 1013 數據提交 {'username': u'aaa', 'user_group_id': 1} 6 [<User_NEW: Charles>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: QQ>, <User_NEW: wahaha>, <User_NEW: aaa>] [26/Jun/2016 17:46:34] "POST /create_user/ HTTP/1.1" 200 1141
經過get的方式獲取想要查詢的數據:
一、直接get獲取數據庫中的數據
def create_user(request): obj = ForgienForm.UserForm(request.POST) if request.method =="POST": print "數據提交" #print request.POST if obj.is_valid(): all_data = obj.clean() print all_data #獲取對象 # group_obj = models.UserGroup_NEW.objects.get(all_data['use_group']) 方式1 經過對象級別插入數據,group_obj表明對象,是一列數據 # models.User_NEW.objects.create(hostname=all_data['username'], # user_group=group_obj) # models.User_NEW.objects.create(hostname=all_data['username'], # user_group_id=all_data['user_group']) #方式2:能夠經過兩種方式插入數據,默認在Django中插入外鍵會加_id, #此種方法能夠直接插入數據 models.User_NEW.objects.create(**all_data) #將方式2直接修改成此種方式建立數據 print models.User_NEW.objects.all().count() else: pass val = request.GET.get('username') #經過get的方式獲取數據 user_list = models.User_NEW.objects.filter(username=val) #數據查詢 # user_list = models.User_NEW.objects.all() #數據查詢 print user_list return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
二、get經過對象獲取數據
####經過雙下劃線實現 def create_user(request): obj = ForgienForm.UserForm(request.POST) if request.method =="POST": print "數據提交" #print request.POST if obj.is_valid(): all_data = obj.clean() print all_data #獲取對象 # group_obj = models.UserGroup_NEW.objects.get(all_data['use_group']) 方式1 經過對象級別插入數據,group_obj表明對象,是一列數據 # models.User_NEW.objects.create(hostname=all_data['username'], # user_group=group_obj) # models.User_NEW.objects.create(hostname=all_data['username'], # user_group_id=all_data['user_group']) #方式2:能夠經過兩種方式插入數據,默認在Django中插入外鍵會加_id, #此種方法能夠直接插入數據 models.User_NEW.objects.create(**all_data) #將方式2直接修改成此種方式建立數據 print models.User_NEW.objects.all().count() else: pass # val = request.GET.get('username') #經過get的方式獲取數據 # user_list = models.User_NEW.objects.filter(username=val) #數據查詢 # user_list = models.User_NEW.objects.all() #數據查詢 val = request.GET.get('usergroup') #get獲取對象的數據,經過__實現 user_list = models.User_NEW.objects.filter(user_group__caption=val) print user_list return render(request,'foreign/create_user.html',{'obj':obj,'user_list':user_list})
注意:一、在連表操做的時候,ForeignKey對應的行表示對象;二、添加數據的時候,默認須要在對應的列的名稱後面加_id;三、獲取數據的時候,若是是使用模板語言,可使用item.user_group.caption來獲取另一張表的數據;若是使用filter查詢指定的數據,使用雙下劃線__來得到另一張表對應的數據;
總結做業:
一、user_group對應對象;
二、建立數據 user_group_id;
三、獲取數據 經過模板加.
四、查詢數據 filter加__ 兩個下劃線表示跨一張表;
若是存在多張表經過外鍵進行關聯:經過.filter(user_group__aa__name)進行數據查詢
class A(models.Model): name = models.CharField(max_length=12) class UserGroup_NEW(models.Model): caption = models.CharField(max_length=64) aa = models.ForeignKey('A') def __unicode__(self): return self.caption class User_NEW(models.Model): username = models.CharField(max_length=64) user_group = models.ForeignKey('UserGroup_NEW') #默認建立的外鍵會加上_id,可使用db_clomn來修改成自定義的列名 def __unicode__(self): return self.username # .filter(user_group__aa__name)
後臺也可使用.連表來取數據:
for item in user_list:
print item.user_group.caption
做業:
xx管理: 1、登陸form 2、session 結合裝飾器 3、裝飾器 4、主機、主機組進行關聯; 添加:主機,主機組; 刪除 修改 查