Django web 進階

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/'
settings

爲何?python

def static(request):
    """
    Adds static-related context variables to the context.
    """
    return {'STATIC_URL': settings.STATIC_URL}
from django.core.context_processors import static

對於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")),
]
urls
from django.conf.urls import url,include
from django.contrib import admin
from  app01.views import account

urlpatterns = [
    url(r'^login/', account.login),
]
app01/urls
#!/usr/bin/env python
# _*_ coding:utf-8 _*_

from django.shortcuts import render
def login(request):
    return render(request, "account/login.html")
account.py
{% 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>
login.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進行設置
form\account.py

二、普通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})       #沒有封裝數據的對象
views\account.py

 

採用以下方式,會保存用戶名:數據庫

#!/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})       #沒有封裝數據的對象
views/account.py

或者: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})
views/account.py

 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對象")
views\account.py
{% 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>
login.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 ""
templatetags\xx.py

 

下面利用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對象")
views\account.py
{% 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>
login.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})
views\home.py
#!/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
forms\home.py
<!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>
index.html
[[1, "Charles"], [2, "www"],[3,"ddddd"],[4,"gggggg"]]
db_admin

 

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
forms\home.py

 

 

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
app01\model
#!/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})
views\home.py

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
app01\model.py

經過admin來管理數據庫表:

from django.contrib import admin

# Register your models here.
from app01 import models
admin.site.register(models.UserInfo)
app01\admin.py

 

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()
model字段

 

 

 

下面介紹經過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>
template/home/upload.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')
app01/views/home.py

 

 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列爲外鍵
app01/model.py

>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進行關聯
app01/model.py

 

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')   #一對一兩張表關聯
app01/model.py

 

 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()    #獲取第一條數據
View Code

刪:

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)
app01/model.py

二、表數據的增長和查詢:

#!/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})
app01/views/home.py

三、替代以前將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
View Code

四、將該數據庫能夠經過admin後臺進行管理:

from django.contrib import admin

# Register your models here.
from app01 import models
admin.site.register(models.UserInfo)
admin.site.register(models.SimpleModel)
app01/admin.py

 

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

默認的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的最大值、最小值、和、個數等;
View Code

 

 連表操做(數據庫數據插入和數據查詢展現),一對多操做

一、建立用戶組表和用戶組表,並經過外鍵進行關聯

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
app01/models.py

二、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')
app01/forms/foreign.py

三、數據插入方式有兩種: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})
app01/views/foreign.py

四、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>
create_user.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})
app01/views/foreign.py

二、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})
app01/views/foreign.py

注意:一、在連表操做的時候,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、主機、主機組進行關聯;
      添加:主機,主機組;
      刪除
      修改
      查
相關文章
相關標籤/搜索