欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python -- pycurl, mysqlclient, Django

系統(tǒng) 1632 0

前言

本不想多說什么,年后在公司親歷一段別樣經(jīng)驗,不想吐槽,只因吐槽不能改變?nèi)魏维F(xiàn)狀。小姐心態(tài),寡婦待遇,婦聯(lián)追求,一份技術(shù)工作做出彎腰,低頭,下跪,也是醉了。今年大環(huán)境不好,大廠裁員,人才過盛,好在自己還是去了符合自己意愿的公司。
新工作快一個月,主要工作技術(shù)內(nèi)容是一個Django的小東西,首先是需要從Python2 遷移至Python3,簡單帶點重構(gòu)。

Python2 遷移Python3 運行環(huán)境

服務(wù)run在docker里,啟動方式里面沒有嵌入太多環(huán)境變量,基本基礎(chǔ)環(huán)境。但是Django自身依賴一些庫環(huán)境需要解決。

pycurl

安裝 pycurl可能會遇到 ssl lib的Error,建議執(zhí)行:

            
              
                export
              
               PYCURL_SSL_LIBRARY
              
                =
              
              openssl

              
                export
              
               LDFLAGS
              
                =
              
              -L/usr/local/opt/openssl/lib

              
                export
              
               CPPFLAGS
              
                =
              
              -I/usr/local/opt/openssl/include


              
                # 執(zhí)行上述環(huán)境變量設(shè)之后,再安裝
              
              
pip 
              
                install
              
               pycurl

            
          

mysqlclient

mysqlclient比較坑,安裝時候會拋出: library not found for -lssl

            
              running build_ext
building 'MySQLdb._mysql' extension
creating build/temp.macosx-10.9-x86_64-3.7
creating build/temp.macosx-10.9-x86_64-3.7/MySQLdb
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch x86_64 -g -Dversion_info=(1,4,2,'post',1) -D__version__=1.4.2.post1 -I/usr/local/opt/mysql@5.7/include/mysql -I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m -c MySQLdb/_mysql.c -o build/temp.macosx-10.9-x86_64-3.7/MySQLdb/_mysql.o
gcc -bundle -undefined dynamic_lookup -arch x86_64 -g build/temp.macosx-10.9-x86_64-3.7/MySQLdb/_mysql.o -L/usr/local/opt/mysql@5.7/lib -lmysqlclient -lssl -lcrypto -o build/lib.macosx-10.9-x86_64-3.7/MySQLdb/_mysql.cpython-37m-darwin.so
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: command 'gcc' failed with exit status 1

            
          

mysqlclient 官網(wǎng)上給出了比較清晰的安裝方式https://github.com/PyMySQL/mysqlclient-python

debian

centos和debian下還比較好解決,直接系統(tǒng)安裝 dev包即可

            
              
                # 先安裝
              
              
                apt-get
              
              
                install
              
               python-dev default-libmysqlclient-dev

              
                # 再安裝mysqlclient
              
              
pip 
              
                install
              
               mysqlclient

            
          

MacOS

MacOS下問題比較多,官網(wǎng)上給的很清楚,mysql-connector-c有bug

            
              
                # 首先安裝mysql
              
              
brew install mysql@
              
                5.7
              
              
                # 安裝 mysql-connector-c
              
              
brew install mysql
              
                -
              
              connector
              
                -
              
              c

            
          

編輯/usr/local/bin/mysql_config 確保:
libs="-L$pkglibdir"

libs="$libs -lmysqlclient -lssl -lcrypto"

            
              
                # 修改/usr/local/bin/mysql_config
              
              
vim /usr/local/bin/mysql_config

              
                # 設(shè)置openssl環(huán)境變量
              
              
                export
              
               PATH
              
                =
              
              
                "/usr/local/opt/openssl/bin:
                
                  $PATH
                
                "
              
              
                export
              
               LDFLAGS
              
                =
              
              
                "-L/usr/local/opt/openssl/lib"
              
              
                export
              
               CPPFLAGS
              
                =
              
              
                "-I/usr/local/opt/openssl/include"
              
              
                # 再安裝mysqlclient
              
              
pip 
              
                install
              
               mysqlclient

            
          

基本環(huán)境設(shè)置好,直接安裝依賴即可

Django

貌似最初開始接觸Python就是Django,從Python2至Python3也不是一個容易的過程

Django 版本差異

1,python2.x下,Django最多支持版本應(yīng)該是1.11,目前Django 都2.2了,中間相差太多
Python3下建議使用高版本
2,djangorestframework是Django用來做純RESTFull API的,官網(wǎng)介紹如下:
https://www.django-rest-framework.org/#quickstart
并且新版本的設(shè)計使用方式,偏向于router register viewset形式,配合action:
https://www.django-rest-framework.org/api-guide/viewsets/
注意
1,低版本djangorestframework不支持 action寫法,建議使用最新版本
2,router 寫法需要嚴(yán)格村從RESTFull形式,router.register prefix中不支持 'pre/fix'形式,action中url_path也不支持 '/'和'.'

APPEND_SLASH

Django 在路由傳統(tǒng)路由匹配時,會有結(jié)尾 ‘/’的區(qū)分,router.register和action中都是默認(rèn)以‘/’結(jié)尾,

            
              urlpatterns 
              
                =
              
              
                [
              
              
    url
              
                (
              
              r
              
                '^user/$'
              
              
                ,
              
               views
              
                .
              
              NodeView
              
                .
              
              as_view
              
                (
              
              
                )
              
              
                )
              
              
                ,
              
              
                # url(r'^user$', views.NodeView.as_view()),
              
              
                ]
              
            
          

以上兩種實質(zhì)是不一樣的uri,但是Django默認(rèn)APPEND_SLASH=True的,當(dāng):

            
              MIDDLEWARE 
              
                =
              
              
                [
              
              
                .
              
              
                .
              
              
                .
              
              
                'django.middleware.common.CommonMiddleware'
              
              
                ,
              
              
                .
              
              
                .
              
              
                .
              
              
                ]
              
            
          

middleware 中開啟CommonMiddleware,會對用戶訪問 http://doamin/user 進(jìn)行自動redirect 至 http://doamin/user/
遷移過程中,很多url不規(guī)范,都是 r'^user$' 形式,整合到router.register形式就會有重定向問題,不僅如此,在主urls.py文件中:

            
              urlpatterns 
              
                =
              
              
                [
              
              
                .
              
              
                .
              
              
                .
              
              
    url
              
                (
              
              r
              
                '.*'
              
              
                ,
              
               views
              
                .
              
              main_view
              
                )
              
              
                ,
              
              
                # 沒收所有沒有匹配上的
              
              
                ]
              
              

@login_required

              
                def
              
              
                main_view
              
              
                (
              
              request
              
                )
              
              
                :
              
              
                return
              
               TemplateResponse
              
                (
              
              request
              
                ,
              
              
                'index.html'
              
              
                )
              
            
          

這種形式構(gòu)造,原本 http://doamin/user 完全可以urlpatterns中未匹配任何,之后缺少 結(jié)尾’/'后重定向匹配http://doamin/user/,
現(xiàn)在被 r'.*' 沒收,返回index界面,而且還需要是login的,否則跳轉(zhuǎn)到login界面

proxy

django-proxy庫用來對一個request進(jìn)行proxy轉(zhuǎn)發(fā),在多數(shù)整合系統(tǒng)中用來做一個簡單gateway很是便捷,Django自帶的Redirect是
本域內(nèi)的重定向,并非轉(zhuǎn)發(fā)。https://github.com/mjumbewu/django-proxy,用法也很清晰。
關(guān)閉APPEND_SLASH=False,對上面自動重定向問題進(jìn)行手動處理,自動匹配所有user prefix下的所有未具有’/'請求:

            
              
                from
              
               proxy
              
                .
              
              views 
              
                import
              
               proxy_view


              
                def
              
              
                main_view
              
              
                (
              
              request
              
                )
              
              
                :
              
              
    path
              
                ,
              
               host 
              
                =
              
               request
              
                .
              
              path
              
                ,
              
               request
              
                .
              
              get_host
              
                (
              
              
                )
              
              
                if
              
               path
              
                .
              
              startswith
              
                (
              
              
                '/user/'
              
              
                )
              
              
                and
              
              
                not
              
               path
              
                .
              
              endswith
              
                (
              
              
                '/'
              
              
                )
              
              
                :
              
              
                return
              
               proxy_view
              
                (
              
              request
              
                ,
              
               f
              
                'http://{host}{path}/'
              
              
                )
              
              

@login_required

              
                def
              
              
                logined_view
              
              
                (
              
              request
              
                )
              
              
                :
              
              
                return
              
               TemplateResponse
              
                (
              
              request
              
                ,
              
              
                'index.html'
              
              
                )
              
            
          

原有 r'.*' 在urlpatterns最末尾,訪問http://doamin/user/直接就匹配上,訪問http://doamin/user被 r'.*' 匹配,而后對
request中的path進(jìn)行判定,如果是/user/起始前綴的,并且沒有’/‘結(jié)尾,補充’/'后重新訪問。
注意
此處用proxy,并非redirect,因為關(guān)于APPEND_SLASH的說明中給出,對于APPEND_SLASH會丟失 POST訪問,所以此處用proxy一并解決

Django User

默認(rèn)Django在 request 中獲取user,即為獲取User model中對應(yīng)的訪問user

            
              
                def
              
              
                response_func
              
              
                (
              
              request
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              request
              
                .
              
              user
              
                )
              
            
          

背后跟session關(guān)聯(lián)的,關(guān)于Django session的設(shè)定,Django session 官網(wǎng)給了比較詳細(xì)的介紹

            
              MIDDLEWARE 
              
                =
              
              
                [
              
              
                .
              
              
                .
              
              
                .
              
              
                'django.contrib.sessions.middleware.SessionMiddleware'
              
              
                ,
              
              
                .
              
              
                .
              
              
                .
              
              
                'django.contrib.auth.middleware.AuthenticationMiddleware'
              
              
                ,
              
              
                .
              
              
                .
              
              
                .
              
              
                ]
              
            
          

中通過利用session確定用戶。

            
              
                class
              
              
                SessionMiddleware
              
              
                (
              
              MiddlewareMixin
              
                )
              
              
                :
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
               get_response
              
                =
              
              
                None
              
              
                )
              
              
                :
              
              
        self
              
                .
              
              get_response 
              
                =
              
               get_response
        engine 
              
                =
              
               import_module
              
                (
              
              settings
              
                .
              
              SESSION_ENGINE
              
                )
              
              
        self
              
                .
              
              SessionStore 
              
                =
              
               engine
              
                .
              
              SessionStore

    
              
                def
              
              
                process_request
              
              
                (
              
              self
              
                ,
              
               request
              
                )
              
              
                :
              
              
        session_key 
              
                =
              
               request
              
                .
              
              COOKIES
              
                .
              
              get
              
                (
              
              settings
              
                .
              
              SESSION_COOKIE_NAME
              
                )
              
              
        request
              
                .
              
              session 
              
                =
              
               self
              
                .
              
              SessionStore
              
                (
              
              session_key
              
                )
              
            
          

settings.SESSION_ENGINE 設(shè)置了session的存儲引擎,默認(rèn) django.contrib.sessions.backends.db 就是用db
settings.SESSION_COOKIE_NAME默認(rèn)的名稱 sessionid 表示在session在cookie標(biāo)志
通過request中cookie獲取sessionid對應(yīng)的值,此值就是 session_key
middleware AuthenticationMiddleware判定SessionMiddleware中打包的 request.session如果沒有觸發(fā)后續(xù)
的操作,正常是存在session,開始生成 request.user

            
              
                def
              
              
                get_user
              
              
                (
              
              request
              
                )
              
              
                :
              
              
                if
              
              
                not
              
              
                hasattr
              
              
                (
              
              request
              
                ,
              
              
                '_cached_user'
              
              
                )
              
              
                :
              
              
        request
              
                .
              
              _cached_user 
              
                =
              
               auth
              
                .
              
              get_user
              
                (
              
              request
              
                )
              
              
                return
              
               request
              
                .
              
              _cached_user



              
                class
              
              
                AuthenticationMiddleware
              
              
                (
              
              MiddlewareMixin
              
                )
              
              
                :
              
              
                def
              
              
                process_request
              
              
                (
              
              self
              
                ,
              
               request
              
                )
              
              
                :
              
              
                assert
              
              
                hasattr
              
              
                (
              
              request
              
                ,
              
              
                'session'
              
              
                )
              
              
                ,
              
              
                (
              
              
                "The Django authentication middleware requires session middleware "
              
              
                "to be installed. Edit your MIDDLEWARE%s setting to insert "
              
              
                "'django.contrib.sessions.middleware.SessionMiddleware' before "
              
              
                "'django.contrib.auth.middleware.AuthenticationMiddleware'."
              
              
                )
              
              
                %
              
              
                (
              
              
                "_CLASSES"
              
              
                if
              
               settings
              
                .
              
              MIDDLEWARE 
              
                is
              
              
                None
              
              
                else
              
              
                ""
              
              
                )
              
              
        request
              
                .
              
              user 
              
                =
              
               SimpleLazyObject
              
                (
              
              
                lambda
              
              
                :
              
               get_user
              
                (
              
              request
              
                )
              
              
                )
              
            
          

真正獲取user是 auth.get_user(request)

            
              
                def
              
              
                get_user
              
              
                (
              
              request
              
                )
              
              
                :
              
              
                """
    Return the user model instance associated with the given request session.
    If no user is retrieved, return an instance of `AnonymousUser`.
    """
              
              
                from
              
              
                .
              
              models 
              
                import
              
               AnonymousUser
    user 
              
                =
              
              
                None
              
              
                try
              
              
                :
              
              
        user_id 
              
                =
              
               _get_user_session_key
              
                (
              
              request
              
                )
              
              
        backend_path 
              
                =
              
               request
              
                .
              
              session
              
                [
              
              BACKEND_SESSION_KEY
              
                ]
              
              
                except
              
               KeyError
              
                :
              
              
                pass
              
              
                else
              
              
                :
              
              
                if
              
               backend_path 
              
                in
              
               settings
              
                .
              
              AUTHENTICATION_BACKENDS
              
                :
              
              
            backend 
              
                =
              
               load_backend
              
                (
              
              backend_path
              
                )
              
              
            user 
              
                =
              
               backend
              
                .
              
              get_user
              
                (
              
              user_id
              
                )
              
              
                # Verify the session
              
              
                if
              
              
                hasattr
              
              
                (
              
              user
              
                ,
              
              
                'get_session_auth_hash'
              
              
                )
              
              
                :
              
              
                session_hash 
              
                =
              
               request
              
                .
              
              session
              
                .
              
              get
              
                (
              
              HASH_SESSION_KEY
              
                )
              
              
                session_hash_verified 
              
                =
              
               session_hash 
              
                and
              
               constant_time_compare
              
                (
              
              
                    session_hash
              
                ,
              
              
                    user
              
                .
              
              get_session_auth_hash
              
                (
              
              
                )
              
              
                )
              
              
                if
              
              
                not
              
               session_hash_verified
              
                :
              
              
                    request
              
                .
              
              session
              
                .
              
              flush
              
                (
              
              
                )
              
              
                    user 
              
                =
              
              
                None
              
              
                return
              
               user 
              
                or
              
               AnonymousUser
              
                (
              
              
                )
              
              
                def
              
              
                _get_user_session_key
              
              
                (
              
              request
              
                )
              
              
                :
              
              
                # This value in the session is always serialized to a string, so we need
              
              
                # to convert it back to Python whenever we access it.
              
              
                return
              
               get_user_model
              
                (
              
              
                )
              
              
                .
              
              _meta
              
                .
              
              pk
              
                .
              
              to_python
              
                (
              
              request
              
                .
              
              session
              
                [
              
              SESSION_KEY
              
                ]
              
              
                )
              
            
          

嘗試通過session中附加的信息,獲取user_id,而后獲取user,完成request中融入 user信息。

Django Https

來由是Django SECURE_PROXY_SSL_HEADER 參數(shù)。一般服務(wù)都是 cluster,如果要做Https,證書都是配在LB上,基本訪問:

            
              Customer  --https-->   LB  --http-->  Service

            
          

在service訪問時有類似的auth驗證,掃碼登陸,結(jié)果service 拿到的 request從LB流入,是http 的協(xié)議,
轉(zhuǎn)而掃碼登陸后redirect的原始的 鏈接就是 http的地址。此時如果LB上配置了 http 強制跳轉(zhuǎn) https即OK,倘若沒有,則新用戶https訪問,跳轉(zhuǎn)掃碼登陸頁,掃碼后轉(zhuǎn)入了 http訪問。

其實Django提供了解決方法:

            
              
                # Django setting 中設(shè)置
              
              
SECURE_PROXY_SSL_HEADER 
              
                =
              
              
                (
              
              
                'HTTP_X_FORWARDED_PROTOCOL'
              
              
                ,
              
              
                'https'
              
              
                )
              
            
          

原文說明:
A tuple representing a HTTP header/value combination that signifies a request is secure. This controls the behavior of the request object’s is_secure() method.

By default, is_secure() determines if a request is secure by confirming that a requested URL uses https://. This method is important for Django’s CSRF protection, and it may be used by your own code or third-party apps.

If your Django app is behind a proxy, though, the proxy may be “swallowing” the fact that a request is HTTPS, using a non-HTTPS connection between the proxy and Django. In this case, is_secure() would always return False – even for requests that were made via HTTPS by the end user.

In this situation, configure your proxy to set a custom HTTP header that tells Django whether the request came in via HTTPS, and set SECURE_PROXY_SSL_HEADER so that Django knows what header to look for.

Django setting中包含參數(shù)特別多,建議查看官網(wǎng) Django Setting 通篇了解下。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 男人的天堂av2017在线 | 黄色毛片免费看 | 久久久久久亚洲 | 成人午夜视频在线观看 | 成人亚洲视频 | 操人视频在线观看 | 国产嫩草影院在线观看 | 久热官网 | 浮力影院在线 | 国产精品不卡一区 | 免费观看一级特黄欧美大片 | 久久涩涩| 日韩欧美在线视频不卡免费视频 | 亚洲碰碰 | 日韩成人免费视频 | 99爱在线观看 | 99久久99久久精品免费看蜜桃 | 国产一区二区三区在线看片 | 视频一区在线观看 | 成人午夜精品视频在线观看 | 黄色一级大片在线免费看产 | 成年人激情在线 | 91精品天美精东蜜桃传媒入口 | 男人天堂av网站 | 99热人人 | 日韩福利网站 | 奇米狠狠操 | 日韩精品一区二区在线观看 | 日本一区二区三区免费观看 | 国产精品一区视频 | av 一区二区三区 | 久久久久国产一区二区三区四区 | 久久精品免费视频观看 | 国内精品视频区在线2021 | 精品美女 | 亚洲国产第一区 | www.色婷婷| 精品久久久久久久人人人人传媒 | a视频在线播放 | 热久热| 污在线视频 |