django里的那些事兒

一佑力、CBV版視圖
二式散、給視圖加裝飾器
三、request對象常用屬性
四打颤、url:路由系統(tǒng)
五暴拄、命名url和url的反向解析
六、session
七编饺、使用 pymysql 連接 mysql
八乖篷、內(nèi)置auth認(rèn)證
九、模板語法中的for循環(huán)

django官方文檔:django-documentation

  • 一透且、CBV版視圖

    veiw中寫函數(shù)有兩種寫法撕蔼,之前寫的def類都是FBV版。還有一種寫法是CBV版秽誊。就是將之前函數(shù)的寫法變類的寫法鲸沮,url中也要相應(yīng)變動一下。

    例:

    視圖中定義:
       from django.views import View
    
       Class AddBook(View):
           def dispatch(self, request, *args, **kwargs):
               print('處理請求之前')
               ret = super().dispatch(request, *args, **kwargs)
               print('處理請求之后')
               return ret
           def get(self,request):
               pass
           def post(self,request):
               pass
    
    url中使用:
        url(r'^add_book/$',views.AddBook.as_view())
    
    執(zhí)行過程:
           1锅论,AddBook這個類讼溺,執(zhí)行了as_view()這個方法,但是棍厌,我們自定義的類里沒有寫這個方法肾胯;
              這就要看繼承的父類里,View類有沒有了耘纱,查看敬肚,有此方法,是類方法束析。
    
           2艳馒,這個類方法執(zhí)行到最后返回了一個view函數(shù),不帶括號,沒有執(zhí)行弄慰,等待連接后才執(zhí)行第美。
                 
           3,view函數(shù)執(zhí)行到最后返回了一個dispatch函數(shù)且執(zhí)行后的結(jié)果陆爽。
              self = cls(**initkwargs) 實例化了一個對象
              return self.dispatch(request, *args, **kwargs)
              此時如果自己寫的類里有dispatch方法則會執(zhí)行自己的什往,沒有則會執(zhí)行父類的
                 
           4,dispatch(派遣的意思)函數(shù)過程中對接收到的請求方式進(jìn)行了判斷慌闭,并對其進(jìn)行了反射别威,
              handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
              反射得出方法
              如果是get則執(zhí)行g(shù)et函數(shù),如果是post則執(zhí)行post函數(shù)驴剔,并將執(zhí)行結(jié)果返回省古。
              return handler(request, *args, **kwargs)
              執(zhí)行并返回結(jié)果
              父類的dispatch(self, request, *args, **kwargs):方法
              是執(zhí)行自己寫的get/post函數(shù)的一個過程。
    
    
    理解dispatch:
              上述分析丧失,函數(shù)走到dispatch后豺妓,是一個對象方法,如果在自己的類里寫了此方法布讹,那么他會走自己的方法琳拭。
              但是,父類有這個方法為什么還要自己寫呢炒事?走自己的方法有什么用呢臀栈?
              那就要看你的需求了蔫慧,函數(shù)走到那一步就會走dispatch這個函數(shù)挠乳,
              如果自己感覺累了,想要先停一會兒姑躲,你就停幾分鐘睡扬,過一會兒再拿過來父類的dispatch運(yùn)行,
              因為你自己的dispatch方法沒有父類的功能黍析,所以還得借用父類的dispatch方法卖怜。
    
    
    簡版的流程:
             AddPublisher.as_view()   ——》 view 函數(shù)
             當(dāng)請求來的時候才執(zhí)行view
             view中執(zhí)行:
                   1. 先實例化AddPublisher,給self
                   2. 執(zhí)行self.dispatch()
                      self 有dispatch 就執(zhí)行自己的
                      沒有就是執(zhí)行 父類(View)的dispatch方法
                   3. dispatch中執(zhí)行:
                      先通過反射獲取到AddPublisher中定義get或者post方法阐枣。
                      執(zhí)行g(shù)et或者post方法 返回httpresponse對象
                   4. view接收到dispatch的返回值——httpresponse對象
                   5. view返回httpresponse對象
    
  • 二马靠、給視圖加裝飾器

    裝飾器:
          def wrapper(func):
              def inner(*args, **kwargs):
                  start_time = time.time()
                  ret = func(*args, **kwargs)
                  end_time = time.time()
                  print("used:", end_time-start_time)
                  return ret
              return inner
    
    # FBV版添加裝飾器
    @wrapper
    def add_class(request):
        if request.method == "POST":
            class_name = request.POST.get("class_name")
            models.Classes.objects.create(name=class_name)
            return redirect("/class_list/")
        return render(request, "add_class.html")
    
    # CBV版添加裝飾器
    from django.views import View
    from django.utils.decorators import method_decorator
    
    第一種:(給各自加)
        class AddClass(View):
    
            @method_decorator(wrapper)
            def get(self, request):
                pass
    
            @method_decorator(wrapper)
            def post(self, request):
                pass
    
    第二種:(給dispatch加)
        class AddClass(View):
    
            @method_decorator(wrapper)
            def dispatch(self, request, *args, **kwargs):
                print('before')
                obj = super(Login,self).dispatch(request, *args, **kwargs)
                print('after')
                return obj
    
            def get(self, request):
                pass
    
            def post(self, request):
                pass
    
    第三種:(給類加)
        @method_decorator(wrapper,name='get')
        @method_decorator(wrapper,name='post')
        class AddClass(View):
    
            def get(self, request):
                pass
    
            def post(self, request):
                pass
    
  • 三、request對象常用屬性

    request.method 請求方式 GET POST
    request.GET    字典蔼两,URL上傳的參數(shù)
    request.POST   字典甩鳄,form表單傳的數(shù)據(jù)
    request.COOKIES.get  獲取cookie信息
    request.session.get  獲取session信息
    request.is_ajax()  判斷請求是不是ajax
    
    request.path_info ---》/add_publisher/ 用戶訪問的URL,不包括域名
    request.body      ---》一個字符串额划,代表請求報文的主體妙啃。在處理非 HTTP 形式的報文時非常有用,例如:二進(jìn)制圖片、XML,Json等揖赴。
                           但是馆匿,如果要處理表單數(shù)據(jù)的時候,推薦還是使用 HttpRequest.POST 燥滑。
    request.FILES     ---》一個類似于字典的對象渐北,包含所有的上傳文件信息。
                            FILES 中的每個鍵為<input type="file" name="" /> 中的name铭拧,值則為對應(yīng)的數(shù)據(jù)腔稀。
                            注意:FILES 只有在請求的方法為POST 且提交的<form> 帶有enctype="multipart/form-data" 的情況下才會
                            包含數(shù)據(jù)。否則羽历,F(xiàn)ILES 將為一個空的類似于字典的對象焊虏。
    
    request.get_full_path() -->/test/?id=1  參數(shù)也拿到了
    request.path_info       -->/test/       只拿到了url
    
    request.get_host     -->IP+端口  127.0.0.1:8000
    
  • 四、url:路由系統(tǒng)

    (1) urlpatterns = [
                url(正則表達(dá)式秕磷,views視圖诵闭,參數(shù),別名)
                ]
    
    (2) ^ 以...為開頭澎嚣,$以...為結(jié)尾
    
    (3) 如果項目中沒有按照自己以為的去執(zhí)行函數(shù)疏尿,可能是因為正則匹配過程中匹配到了別的。
          匹配時從上往下依次匹配易桃,如果上面有符合要求的褥琐,就不會走下面的。
          url(r'^book/',)
          url(r'^book/asd')
          一般可寫成url(r'^book/$')規(guī)定開頭結(jié)尾晤郑,約束
    
    (4)  url位置參數(shù)說明:
         # 用戶輸入url敌呈,滿足條件匹配上之后,才能將參數(shù)傳進(jìn)test函數(shù)造寝,讓test函數(shù)對url中分組內(nèi)的參數(shù)進(jìn)行處理磕洪。
         # 即用戶可通過url輸入?yún)?shù),url匹配成功后诫龙,通過url進(jìn)行傳參析显,傳括號里的內(nèi)容傳給函數(shù)進(jìn)行處理。
         無名分組:
           實例1:
                用戶輸入:
                    127.0.0.1:8000/test/2018/08
                url:
                    url(r'^test/([0-9]{4})/[0-9]{2}',views.test)
                函數(shù):
                    def test(request,*args,**kwargs):
                        print(args)
                        輸出結(jié)果:('2018',)
                        return HttpResponse('你自己輸入的{},你還愁啥'.format(args))
                        頁面顯示:你自己輸入的('2018',),你還愁啥
    
            實例2:
                用戶輸入:
                    127.0.0.1:8000/test/嘀嗒嘀嗒嘀嗒嘀签赃。谷异。。锦聊。(隨便輸入)
                url:
                    url(r'^test/([0-9]{4})/[0-9]{2}',views.test),不走這個
                    url(r'^test/(.+)',views.test1) 走這個
                函數(shù):
                    def test1(request,*args):
                        return HttpResponse(args[0])
                       頁面顯示:輸入什么就顯示什么
    
                    url(r'^test/(.{3})',views.test1),這個是不管輸入多少歹嘹,只顯示3個字
    
    (5) # 是否開啟URL訪問地址后面不為/,也能跳轉(zhuǎn)至帶有/的路徑的配置項:
          配置中寫入這個,不加/也能自動添加/再走一次
          APPEND_SLASH=True (默認(rèn)為True括丁,所以不寫也能自動添加)
          如果不想讓其自動添加荞下,就改為 False
    
    (6)分組命名匹配:(區(qū)別在于:函數(shù)中只接收正則中命名的名字作為參數(shù),將匹配到的結(jié)果傳給函數(shù))
         有名分組:
         實例:
           用戶輸入:
                  http://127.0.0.1:8000/test/阿斯頓法國紅酒看來
           url中:
                  url(r'^test/(?P<nei_rong>.{2})',views.test2)
           views中:
                  def test2(request,nei_rong):
                     print(nei_rong)
                     輸出結(jié)果:阿斯
                     return HttpResponse('輸入的內(nèi)容為:{}'.format(nei_rong))
                     頁面顯示:輸入的內(nèi)容為:阿斯
    
    (7) 后端接收到的url中的參數(shù)都是字符串!
    
    (8) 視圖函數(shù)中指定默認(rèn)值
          # urls.py中
          from django.conf.urls import url
    
          from . import views
    
          urlpatterns = [
                  url(r'^blog/$', views.page),
                  url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
              ]
    
          # views.py中尖昏,可以為num指定默認(rèn)值
          def page(request, num="1"):
               pass
    
    (9) 包含其他的url:(可將不同url寫進(jìn)不同的業(yè)務(wù)線下仰税,然后用總的包含)
          from django.conf.urls import include, url
          from app01 import urls
    
          urlpatterns = [
             url(r'^admin/', admin.site.urls),
             url(r'^app01/', include('app01.urls')),  # 可以包含其他的URLconfs文件
             【1,不導(dǎo)入抽诉,寫字符串陨簇,反射找到】
    
             from app01 import urls as app01_urls
             url(r'^app01/', include(app01_urls))
             【2,導(dǎo)入迹淌,不用寫成字符串】
          ]
    
    (10) 當(dāng)兩個app寫了兩個相同的url河绽,反向解析時就會沖突,所以要將不同的app下的url寫不同的標(biāo)記唉窃,即
          在總的url中耙饰,命名空間。
          url(r'^app01/', include('app01.urls'),namespace='app01')
          url(r'^app02/', include('app02.urls'),namespace='app02')
    
          反向解析時:
          url = reverse('app01:index')
          url = reverse('app02:index')
    
          起了namespace纹份,都要用app01:加前綴
          url = reverse('app01:book')
    
    (11) url中可傳參數(shù)(可以在url中自己寫一個參數(shù)苟跪,字典中的,傳給views中的相應(yīng)函數(shù))
          urlpatterns = [
              url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
          ]
    
  • 五蔓涧、命名url和url的反向解析

    1件已,起名字:
        url(r'^json/',views.json_data,name='js')
    
    2,用(可在視圖中用元暴,可在模板中用)
        視圖中用:
            導(dǎo)入reverse:
            from django.shortcuts import render,HttpResponse,reverse
    
            url = reverse('js')
            結(jié)果是/json/篷扩,即使改為/jsonfgieue/,也能通過js找到茉盏。通過名字就能找到這個url鉴未,
            比較靈活(不帶參數(shù)的),通過名字援岩,找到url歼狼,字符串類型
    
        模板中用:
            url(r'baidusss/',views.baidu,name='baidu')
            <a href="/baidu/">這是跳轉(zhuǎn)到一個自定義的百度路由(寫死的)掏导,然后返回一個百度的連接</a>
    
            <a href="{% url 'baidu' %}">這個連接用的是反向解析享怀,如果views中的url變了,上面就找不到了</a>
    
    3趟咆,作用:不怕url改名字添瓷。不管怎么改,我的模板中值纱,函數(shù)中鳞贷,都能找到此路由,
          這就給自己提供了方便虐唠,即使路由改了搀愧,html頁面中或函數(shù)中要跳轉(zhuǎn)的路由不用改,只是用戶輸入時需要改。
          因為程序內(nèi)部有這個反向解析的方法能找到咱筛,而用戶只能是提供什么url就寫什么url
    
    4搓幌,帶參數(shù)的用法(無名分組)
            url(r'^testtttttt/([0-9]{4})/([0-9]{2})',views.test,name='test')
    
            視圖中,需傳參
                url = reverse('test',args=('1998','08))
    
            模板中,需傳參
                <a href="{% url 'test' '1998' '08' %}">測試</a>
    
    5迅箩,帶有名分組的參數(shù)
            url(r'^testtttttt/(溉愁?P<year>[0-9]{4})/(?P<month>[0-9]{2})',views.test,name='test')
    
            視圖中,傳位置參數(shù)
                url = reverse('test',kwargs={'year':'1998','month':'08'})
    
            模板中饲趋,傳參
                <a href="{% url 'test' '1998' '08' %}">測試</a> (對應(yīng)先后順序)
                或者
                <a href="{% url 'test' month='08' year='1998' %}">測試</a> (可換位置)
    

    舉個栗子:

    總路由:
    urlpatterns = [
          url(r'^goods/', include('df_goods.urls', namespace='df_goods')),  # 添加實例命名空間
    ]
    
    子路由:
    urlpatterns = [
        url('^index/$', views.index, name="index"),
    ]
    
    視圖應(yīng)用:
    print(reverse("df_goods:index"))  # 利用reverse函數(shù)反向解析url
    # 打印結(jié)果為/goods/index/
    
    頁面應(yīng)用:
    <a href="{% url "df_goods:index" %}">反向解析</a>
    
  • 六拐揭、session

    Cookie雖然解決了“保持狀態(tài)”的需求,但是cookie最大支持4096字節(jié)奕塑,且cookie保存在客戶端堂污,可能被攔截或竊取。
    
    因此就需要有一種新的東西龄砰,支持更多字節(jié)敷鸦,并且保存在服務(wù)器,有較高的安全性寝贡,這就是Session扒披。
    
    Session
        1,接收請求圃泡,返回響應(yīng)
        2碟案,返回響應(yīng)時,生成一個特殊的字符串
        3颇蜡,在后端開一塊空間价说,保存請求相關(guān)數(shù)據(jù)
        4,返回響應(yīng)
    
        下一次請求時:
            1风秤,帶著之前發(fā)給瀏覽器的字符串
            2鳖目,拿著字符串找相應(yīng)的箱子
            3,在箱子中根據(jù)key取值
    
    前提:django存儲session是在內(nèi)置的 django_session 表中缤弦,所以必須先生成其表领迈。
    
    1. 設(shè)置Session:
        不需要在響應(yīng)中設(shè)置,直接request.session['key']='value'
      
        1. request.session[key] = value
        2. request.session.setdefault(key, value)   --> 有就啥都不干碍沐,沒有就賦值
    
    2. 獲取session:
        if request.session.get('key','')== 'value':
            pass
    
        1. request.session[key]
        2. request.session.get(key)  推薦
    
    3. 刪除Session
      1. request.session.delete()
      2. request.session.flush()     --> 刪除Cookie和Session
    
    4. 清空已經(jīng)過期的session數(shù)據(jù)
        request.session.clear_expired()
    
    5. 設(shè)置Session過期時間
        request.session.set_expiry(過期時間)
    
        session中的有效日期狸捅,默認(rèn)是兩周
    
    6. settings配置中:
        SESSION_SAVE_EVERY_REQUEST = True
        # 一般設(shè)為True
        # 每次請求都更新超時時間,超時時間從最近的一次請求算起累提。
    
        SESSION_COOKIE_AGE = 129600 --->默認(rèn)兩周
    
  • 七尘喝、使用 pymysql 連接 mysql

    1,創(chuàng)建mysql數(shù)據(jù)庫
    2斋陪,settings配置:
            DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',
                        'NAME': 'chubanshe_book',
                        'HOST': '127.0.0.1',
                        'POST': 3306,
                        'USER': 'root',
                        'PASSWORD': '',
                    }
                }
    3朽褪,告訴django使用pymysql來連接數(shù)據(jù)庫:
        在與項目同名的文件夾下的__init__.py文件中寫:
        import pymysql
        pymysql.install_as_MySQLdb()
    
    4置吓,在app01/models.py寫類(必須繼承models.Model)
        class Publisher(models.Model):
            id = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32,null=False,unique=True)
    
    5,執(zhí)行數(shù)據(jù)庫遷移兩條命令
        python manage.py makemigrations # 保存models修改記錄
        python manage.py migrate   # 操作數(shù)據(jù)表
    
    
     1         2                3                         4                      5
    創(chuàng)表缔赠,  我要連(配置)交洗,  我要用什么連(pymysql),  形成映射關(guān)系(model)橡淑,  兩條命令
    
  • 八构拳、內(nèi)置auth認(rèn)證

    • auth認(rèn)證:默認(rèn)django內(nèi)置的認(rèn)證系統(tǒng),默認(rèn)在數(shù)據(jù)庫使用auth_user表

    • 擴(kuò)展內(nèi)置user表

      models.py:
        from django.contrib.auth.models import AbstractUser
        class UserInfo(AbstractUser):
            phone = models.CharField(max_length=11)
      
      settings.py:
        AUTH_USER_MODEL = "app01.UserInfo"
      
      views.py:
         models.UserInfo.objects.create_user(password=pwd,username=user,phone=pho)
      
    • django的登錄:auth.login(request,user)

    • django的注銷:auth.logout(request)

    • 用戶是否登陸:request.user.is_authenticated

    • 驗證用戶名密碼是否正確:auth.authenticate(request, username=username, password=pwd)

    • 登錄認(rèn)證裝飾器:login_required
      LOGIN_URL = '/login/' # 配置將內(nèi)置登錄路由替換成自己的登錄路由

    • 登錄用戶顯示用戶名梁棠,非登錄用戶請登錄:user.is_authenticated

    • 檢查原密碼:check_password(password)---> 修改密碼時使用
      auth 提供的一個檢查密碼是否正確的方法置森,需要提供當(dāng)前請求用戶的密碼。
      密碼正確返回True符糊,否則返回False凫海。
      ok = request.user.check_password('密碼')

    • 重置新密碼:set_password(password)---> 修改密碼時使用
      auth 提供的一個修改密碼的方法,接收 要設(shè)置的新密碼 作為參數(shù)男娄。
      注意:設(shè)置完一定要調(diào)用用戶對象的save方法P刑啊!模闲!
      request.user.set_password(密碼)
      request.user.save()

  • 九建瘫、模板語法中的for循環(huán)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市尸折,隨后出現(xiàn)的幾起案子啰脚,更是在濱河造成了極大的恐慌,老刑警劉巖实夹,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件橄浓,死亡現(xiàn)場離奇詭異,居然都是意外死亡亮航,警方通過查閱死者的電腦和手機(jī)荸实,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缴淋,“玉大人准给,你說我怎么就攤上這事⊙缁” “怎么了圆存?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仇哆。 經(jīng)常有香客問我,道長夫植,這世上最難降的妖魔是什么讹剔? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任油讯,我火速辦了婚禮,結(jié)果婚禮上延欠,老公的妹妹穿的比我還像新娘陌兑。我一直安慰自己,他們只是感情好由捎,可當(dāng)我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布兔综。 她就那樣靜靜地躺著,像睡著了一般狞玛。 火紅的嫁衣襯著肌膚如雪软驰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天心肪,我揣著相機(jī)與錄音锭亏,去河邊找鬼。 笑死硬鞍,一個胖子當(dāng)著我的面吹牛慧瘤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播固该,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼锅减,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了伐坏?” 一聲冷哼從身側(cè)響起上煤,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎著淆,沒想到半個月后劫狠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡永部,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年独泞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苔埋。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡懦砂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出组橄,到底是詐尸還是另有隱情荞膘,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布玉工,位于F島的核電站羽资,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏遵班。R本人自食惡果不足惜屠升,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一潮改、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧腹暖,春花似錦汇在、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至殖告,卻和暖如春阿蝶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丛肮。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工赡磅, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宝与。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓焚廊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親习劫。 傳聞我的和親對象是個殘疾皇子咆瘟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,860評論 2 361