python學習隨筆--django 下

緩存

由於Django是動態網站,所有每次請求均會去數據進行相應的操作,當程序訪問量大時,耗時必然會更加明顯,最簡單解決方式是使用:緩存,緩存將一個某個views的返回值保存至內存或者Redis中,5分鐘內再有人來訪問時,則不再去執行view中的操作,而是直接從內存或者Redis中之前緩存的內容拿到,並返回,

#配置:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': os.path.join(BASE_DIR, 'cache'),
        'TIMEOUT': 600,
        'OPTIONS': {
            'MAX_ENTRIES': 1000
        }
    }
} 
#應用
from django.shortcuts import render, HttpResponse
from django.views.decorators.cache import cache_page
 
@cache_page(60 * 15)
def func(request):
    return HttpResponse('xxx')

更多:

  https://docs.djangoproject.com/en/1.9/topics/cache/
  

http://djangobook.py3k.cn/2.0/chapter15/


Cookie和Session

一、操作Cookie

  獲取cookie:request.COOKIES[key]

  設置cookie:response.set_cookie(key,value)

由於cookie保存在客戶端的電腦上,所以,jquery也可以操作cookie。

<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });


二、操作Session

  獲取session:request.session[key]

  設置session:reqeust.session[key] = value

  刪除session:del request[key]

request.session.set_expiry(value)
* 如果value是個整數,session會在些秒數後失效。
* 如果value是個datatime或timedelta,session就會在這個時間後失效。
* 如果value是0,用戶關閉瀏覽器session就會失效。
* 如果value是None,session會依賴全局session失效策略。

更多見:

  https://docs.djangoproject.com/en/1.9/topics/http/sessions/

  http://docs.30c.org/djangobook2/chapter14/

  https://docs.djangoproject.com/en/1.9/ref/settings/#settings-sessions

三、應用

def login(func):
    def wrap(request, *args, **kwargs):
        # 如果未登陸,跳轉到指定頁面
        if request.path == '/test/':
            return redirect('http://www.baidu.com')
        return func(request, *args, **kwargs)
    return wrap

分頁

一、Django內置分頁

Paginator

二、自定義分頁

分頁功能在每個網站都是必要的,對於分頁來說,其實就是根據用戶的輸入計算出應該在數據庫表中的起始位置。

1、設定每頁顯示數據條數

2、用戶輸入頁碼(第一頁、第二頁...)

3、根據設定的每頁顯示條數和當前頁碼,計算出需要取數據表的起始位置

4、在數據表中根據起始位置取值,頁面上輸出數據


需求又來了,需要在頁面上顯示分頁的頁面。如:[上一頁][1][2][3][4][5][下一頁]

1、設定每頁顯示數據條數

2、用戶輸入頁碼(第一頁、第二頁...)

3、設定顯示多少頁號

4、獲取當前數據總條數

5、根據設定顯示多少頁號和數據總條數計算出,總頁數

6、根據設定的每頁顯示條數和當前頁碼,計算出需要取數據表的起始位置

7、在數據表中根據起始位置取值,頁面上輸出數據

8、輸出分頁html,如:[上一頁][1][2][3][4][5][下一頁]

#!/usr/bin/env python
# _*_coding:utf-8_*_
from django.utils.safestring import mark_safe
 
class PageInfo(object):
    def __init__(self,current,totalItem,peritems=5):
        self.__current=current
        self.__peritems=peritems
        self.__totalItem=totalItem
    def From(self):
        return (self.__current-1)*self.__peritems
    def To(self):
        return self.__current*self.__peritems
    def TotalPage(self):  #總頁數
        result=divmod(self.__totalItem,self.__peritems)
        if result[1]==0:
            return result[0]
        else:
            return result[0]+1
 
def Custompager(baseurl,currentPage,totalpage):  #基礎頁,當前頁,總頁數
    perPager=11
    #總頁數<11
    #0 -- totalpage
    #總頁數>11
        #當前頁大於5 currentPage-5 -- currentPage+5
            #currentPage+5是否超過總頁數,超過總頁數,end就是總頁數
        #當前頁小於5 0 -- 11
    begin=0
    end=0
    if totalpage <= 11:
        begin=0
        end=totalpage
    else:
        if currentPage>5:
            begin=currentPage-5
            end=currentPage+5
            if end > totalpage:
                end=totalpage
        else:
            begin=0
            end=11
    pager_list=[]
    if currentPage<=1:
        first="<a href=''>首頁</a>"
    else:
        first="<a href='%s%d'>首頁</a>" % (baseurl,1)
    pager_list.append(first)
 
    if currentPage<=1:
        prev="<a href=''>上一頁</a>"
    else:
        prev="<a href='%s%d'>上一頁</a>" % (baseurl,currentPage-1)
    pager_list.append(prev)
 
    for i in range(begin+1,end+1):
        if i == currentPage:
            temp="<a href='%s%d' class='selected'>%d</a>" % (baseurl,i,i)
        else:
            temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
        pager_list.append(temp)
    if currentPage>=totalpage:
        next="<a href='#'>下一頁</a>"
    else:
        next="<a href='%s%d'>下一頁</a>" % (baseurl,currentPage+1)
    pager_list.append(next)
    if currentPage>=totalpage:
        last="<a href=''>末頁</a>"
    else:
        last="<a href='%s%d'>末頁</a>" % (baseurl,totalpage)
    pager_list.append(last)
    result=''.join(pager_list)
    return mark_safe(result)   #把字符串轉成html語言

分頁實例

總結,分頁時需要做三件事:

  • 創建處理分頁數據的類

  • 根據分頁數據獲取數據

  • 輸出分頁HTML,即:[上一頁][1][2][3][4][5][下一頁]



Model進階

1。基本操作

# 增
    #
    # models.Tb1.objects.create(c1='xx', c2='oo')  增加一條數據,可以接受字典類型數據 **kwargs

    # obj = models.Tb1(c1='xx', c2='oo')
    # obj.save()

    # 查
    #
    # models.Tb1.objects.get(id=123)         # 獲取單條數據,不存在則報錯(不建議)
    # models.Tb1.objects.all()               # 獲取全部
    # models.Tb1.objects.filter(name='seven') # 獲取指定條件的數據

    # 刪
    #
    # models.Tb1.objects.filter(name='seven').delete() # 刪除指定條件的數據

    # 改
    # models.Tb1.objects.filter(name='seven').update(gender='0')  # 將指定條件的數據更新,均支持 **kwargs
    # obj = models.Tb1.objects.get(id=1)
    # obj.c1 = '111'
    # obj.save()                                                 # 修改單條數據

基本操作

2、進階操作(了不起的雙下劃線)

利用雙下劃線將字段和對應的操作連接起來

# 獲取個數
    #
    # models.Tb1.objects.filter(name='seven').count()

    # 大於,小於
    #
    # models.Tb1.objects.filter(id__gt=1)              # 獲取id大於1的值
    # models.Tb1.objects.filter(id__lt=10)             # 獲取id小於10的值
    # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 獲取id大於1 且 小於10的值

    # in
    #
    # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 獲取id等於11、22、33的數據
    # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

    # contains
    #
    # 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])   # 範圍bettwen and

    # 其他類似
    #
    # startswith,istartswith, 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'))
    # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

進階操作

3、連表操作(了不起的雙下劃線)

利用雙下劃線和 _set 將表之間的操作連接起來

class UserProfile(models.Model):
    user_info = models.OneToOneField('UserInfo')
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=64)

    def __unicode__(self):
        return self.username


class UserInfo(models.Model):
    user_type_choice = (
        (0, u'普通用戶'),
        (1, u'高級用戶'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    name = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    address = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name


class UserGroup(models.Model):

    caption = models.CharField(max_length=64)

    user_info = models.ManyToManyField('UserInfo')

    def __unicode__(self):
        return self.caption


class Host(models.Model):
    hostname = models.CharField(max_length=64)
    ip = models.GenericIPAddressField()
    user_group = models.ForeignKey('UserGroup')

    def __unicode__(self):
        return self.hostname

表結構實例
user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password
 
user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys()
print user_info_obj.values()

一對一操作
一對多 類似一對一1、搜索條件使用 __ 連接2、獲取值時使用 .    連接
user_info_obj = models.UserInfo.objects.get(name=u'武沛齊')
user_info_objs = models.UserInfo.objects.all()
 
group_obj = models.UserGroup.objects.get(caption='CEO')
group_objs = models.UserGroup.objects.all()
 
# 添加數據
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)
 
# 刪除數據
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)
 
# 添加數據
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)
 
# 刪除數據
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)
 
# 獲取數據
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)
 
# 獲取數據
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CEO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')

多對多操作
# F 使用查詢條件的值
    #
    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)

    # Q 構建搜索條件
    from django.db.models import Q
    # con = Q()
    #
    # q1 = Q()
    # q1.connector = 'OR'
    # q1.children.append(('id', 1))
    # q1.children.append(('id', 10))
    # q1.children.append(('id', 9))
    #
    # q2 = Q()
    # q2.connector = 'OR'
    # q2.children.append(('c1', 1))
    # q2.children.append(('c1', 10))
    # q2.children.append(('c1', 9))
    #
    # con.add(q1, 'AND')
    # con.add(q2, 'AND')
    #
    # models.Tb1.objects.filter(con)

    #
    # from django.db import connection
    # cursor = connection.cursor()
    # cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
    # row = cursor.fetchone()

其他操作

注意:xx_set中的【_set】是多對多中的固定搭配

擴展:上傳文件實例

class FileForm(forms.Form):
    ExcelFile = forms.FileField()
    
from django.db import modelsclass UploadFile(models.Model):
    userid = models.CharField(max_length = 30)
    file = models.FileField(upload_to = './upload/')
    date = models.DateTimeField(auto_now_add=True)
    
def UploadFile(request):
    uf = AssetForm.FileForm(request.POST,request.FILES)
    if uf.is_valid():
            upload = models.UploadFile()
            upload.userid = 1
            upload.file = uf.cleaned_data['ExcelFile']
            upload.save()
            
            print upload.file

View


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章