Django開發BUG彙總

使用版本知悉

limengjiedeMacBook-Pro:~ limengjie$ python --version

Python 3.6.4 :: Anaconda, Inc.

limengjiedeMacBook-Pro:~ limengjie$ python -m django --version

1.11.13 

工做需求是1.11.13(安裝時,pip版本較低,2.0如下版本安裝會超時,2.0以上版本安裝正常)css

當前系統環境的端口狀況查看:html

# windows
# 查看8000端口
netstat -aon | findstr "8000"

# 倘若此時8000端口被進程號爲15312的進程佔用,繼續執行下面命令查看對應的進程:
tasklist | findstr "15312"

# 倘若查看結果,是被test.py給佔用了,若是不想這個程序繼續佔用,能夠結束該進程:
taskkill /f /t /im test.py
或者直接根據進程號PID殺死該進程
taskkill /f /PID 15312


#mac
# 查看端口:
sudo lsof -i:8000

# 查看結果:
COMMAND PID      USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
python  934 limengjie    4u  IPv4 0xf90e8048abbcccff      0t0  TCP localhost:irdmi (LISTEN)

# 根據進程PID殺進程
sudo kill -9 934
查看系統端口狀況

目錄

  1. mac環境下,安裝Django 2.0 如下版本報錯
  2. 列表存進MySQL數據庫後再讀取時需轉換類型
  3. 上傳與下載
  4. Django調試工具:debug_toolbar

 

 

 

 

 

 

 

 

1、mac環境下,安裝Django 2.0如下版本報錯

使用pycharm安裝異常截圖

使用命令行安裝,異常以下

提示安裝超時,並建議更新pip版本號python

Last login: Thu Jun 14 16:59:22 on ttys000
limengjiedeMacBook-Pro:~ limengjie$ pip install Django==1.11.13
Collecting Django==1.11.13
  Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x10ae0ebe0>, 'Connection to files.pythonhosted.org timed out. (connect timeout=15)')': /packages/25/4d/c8228419346a0e84aec202a43e181afc6572b861d38f8a0306dbce6abef0/Django-1.11.13-py2.py3-none-any.whl
  Downloading https://files.pythonhosted.org/packages/25/4d/c8228419346a0e84aec202a43e181afc6572b861d38f8a0306dbce6abef0/Django-1.11.13-py2.py3-none-any.whl (6.9MB)
    14% |████▊                           | 1.0MB 8.9kB/s eta 0:11:03Exception:
Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/pip/_vendor/requests/packages/urllib3/response.py", line 232, in _error_catcher
    yield
  File "/anaconda3/lib/python3.6/site-packages/pip/_vendor/requests/packages/urllib3/response.py", line 314, in read
    data = self._fp.read(amt)
  File "/anaconda3/lib/python3.6/site-packages/pip/_vendor/cachecontrol/filewrapper.py", line 60, in read
    data = self.__fp.read(amt)
  File "/anaconda3/lib/python3.6/http/client.py", line 449, in read
    n = self.readinto(b)
  File "/anaconda3/lib/python3.6/http/client.py", line 493, in readinto
    n = self.fp.readinto(b)
  File "/anaconda3/lib/python3.6/socket.py", line 586, in readinto
    return self._sock.recv_into(b)
  File "/anaconda3/lib/python3.6/ssl.py", line 1009, in recv_into
    return self.read(nbytes, buffer)
  File "/anaconda3/lib/python3.6/ssl.py", line 871, in read
    return self._sslobj.read(len, buffer)
  File "/anaconda3/lib/python3.6/ssl.py", line 631, in read
    v = self._sslobj.read(len, buffer)
socket.timeout: The read operation timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/anaconda3/lib/python3.6/site-packages/pip/commands/install.py", line 335, in run
    wb.build(autobuilding=True)
  File "/anaconda3/lib/python3.6/site-packages/pip/wheel.py", line 749, in build
    self.requirement_set.prepare_files(self.finder)
  File "/anaconda3/lib/python3.6/site-packages/pip/req/req_set.py", line 380, in prepare_files
    ignore_dependencies=self.ignore_dependencies))
  File "/anaconda3/lib/python3.6/site-packages/pip/req/req_set.py", line 620, in _prepare_file
    session=self.session, hashes=hashes)
  File "/anaconda3/lib/python3.6/site-packages/pip/download.py", line 821, in unpack_url
    hashes=hashes
  File "/anaconda3/lib/python3.6/site-packages/pip/download.py", line 659, in unpack_http_url
    hashes)
  File "/anaconda3/lib/python3.6/site-packages/pip/download.py", line 882, in _download_http_url
    _download_url(resp, link, content_file, hashes)
  File "/anaconda3/lib/python3.6/site-packages/pip/download.py", line 603, in _download_url
    hashes.check_against_chunks(downloaded_chunks)
  File "/anaconda3/lib/python3.6/site-packages/pip/utils/hashes.py", line 46, in check_against_chunks
    for chunk in chunks:
  File "/anaconda3/lib/python3.6/site-packages/pip/download.py", line 571, in written_chunks
    for chunk in chunks:
  File "/anaconda3/lib/python3.6/site-packages/pip/utils/ui.py", line 139, in iter
    for x in it:
  File "/anaconda3/lib/python3.6/site-packages/pip/download.py", line 560, in resp_read
    decode_content=False):
  File "/anaconda3/lib/python3.6/site-packages/pip/_vendor/requests/packages/urllib3/response.py", line 357, in stream
    data = self.read(amt=amt, decode_content=decode_content)
  File "/anaconda3/lib/python3.6/site-packages/pip/_vendor/requests/packages/urllib3/response.py", line 324, in read
    flush_decoder = True
  File "/anaconda3/lib/python3.6/contextlib.py", line 99, in __exit__
    self.gen.throw(type, value, traceback)
  File "/anaconda3/lib/python3.6/site-packages/pip/_vendor/requests/packages/urllib3/response.py", line 237, in _error_catcher
    raise ReadTimeoutError(self._pool, None, 'Read timed out.')
pip._vendor.requests.packages.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
You are using pip version 9.0.1, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
pip install django==1.11.13 報錯源碼

解決方案:

You are using pip version 9.0.1, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

按照提示,更新pip版本後,安裝正常jquery

limengjiedeMacBook-Pro:~ limengjie$ pip install --upgrade pip
Collecting pip
  Downloading https://files.pythonhosted.org/packages/0f/74/ecd13431bcc456ed390b44c8a6e917c1820365cbebcb6a8974d1cd045ab4/pip-10.0.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 23kB/s 
Installing collected packages: pip
  Found existing installation: pip 9.0.1
    Uninstalling pip-9.0.1:
      Successfully uninstalled pip-9.0.1
Successfully installed pip-10.0.1
limengjiedeMacBook-Pro:~ limengjie$ pip install Django==1.11.13
Collecting Django==1.11.13
  Downloading https://files.pythonhosted.org/packages/25/4d/c8228419346a0e84aec202a43e181afc6572b861d38f8a0306dbce6abef0/Django-1.11.13-py2.py3-none-any.whl (6.9MB)
    100% |████████████████████████████████| 7.0MB 30kB/s 
Requirement already satisfied: pytz in /anaconda3/lib/python3.6/site-packages (from Django==1.11.13) (2017.3)
Installing collected packages: Django
  Found existing installation: Django 2.0.6
    Uninstalling Django-2.0.6:
      Successfully uninstalled Django-2.0.6
Successfully installed Django-1.11.13

安裝成功驗證:linux

方法一:git

>>> import django
>>> print django.VERSION # Python2的格式  
>>> print(django.VERSION) # python3版本
(1, 11, 13, 'final', 0)

方法二:(也是經過查看版本號,python -m django --version)github

limengjiedeMacBook-Pro:~ limengjie$ python -m django --version
1.11.13

 


 

2、列表存進MySQL數據庫後再讀取需從新轉換爲列表

問題截圖

此處功能部分源碼:

關鍵是使用eval()函數實現str類型和list,tuple或dict之間的轉換ajax

class UploadFile(View):

    def get(self, request):
        file_list = models.FileObj.objects.all()
        # 將數據庫中的str對象轉爲list對象
        for file_obj in file_list:
            file_obj.fileMsg = eval(file_obj.fileMsg)
        return render(
            request,
            "upload_file.html",
            {"file_list": file_list}
        )

    def post(self, request):
        pass

 


 

 

3、上傳與下載

下載zip壓縮包文件異常截圖

下載文件後,沒法正常打開數據庫

需手動加後綴名修改文件格式方可正常打開
進而能得知文件內容正常
以下圖,給「下載」文件加上後綴便可獲得正常下載的內容django

 

打開網頁檢查,以下圖

發現是Content-Disposition出錯

接下來,就針對這個屬性在網上搜集資料,解決步驟以下:

一、導入模塊

from django.utils.encoding import escape_uri_path

二、重寫該屬性

response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(the_file_name)) # 正確寫法

完整下載功能源碼:

注:其中BUG1和BUG2普通解決方案不是最佳解決途徑

from django.http import StreamingHttpResponse

# 切片讀取文件
def file_iterator(filename,chunk_size=512):
    with open(filename,'rb') as f:
        while True:
            c=f.read(chunk_size)
            if c:
                yield c
            else:
                break

# 下載功能
def download_file(request):
    the_file_name = models.FileObj.objects.get(id=request.GET.get("id")).fileName  # 顯示在彈出對話框中的默認的下載文件名
    print(the_file_name)
    file_path = os.path.join(file_dir,the_file_name) # 要下載的文件路徑
    response = StreamingHttpResponse(file_iterator(file_path))
    response['Content-Type'] = 'application/octet-stream' # #設定文件頭,這種設定可讓任意文件都能正確下載,並且已知文本文件不是本地打開
    # response['Content-Disposition'] = 'attachment;filename="download.zip"' # BUG1:給出一個固定的文件名,且不能爲中文,文件名寫死了
    # response['Content-Disposition'] = 'attachment;filename={0}'.format(the_file_name.encode("utf-8")) # BUG2:中文會亂碼
    response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(the_file_name)) # 正確寫法
    return response

 正常下載zip文件的效果圖:

 正常顯示下載zip文件實例

上傳並解壓rar壓縮包異常截圖

 

參閱RAR官方文檔:http://python-unrar.readthedocs.io/en/v0.3/

得知第三方庫unrar依賴於RAR庫,解決思路就是先導入RAR庫,而後再導入第三方unrar庫便可,具體執行步驟以下:

由於win和linux系統的差別,需分別進行操做:

從python-unrar開源項目官網https://github.com/matiasb/python-unrar/blob/master/README.md

得知了Python下的unrar還依賴RAR官方的庫。 那麼,接下來就分Windows和Linux兩個系統來介紹解決步驟。 Win:
1. 先到RARLab官方下載庫文件,http://www.rarlab.com/rar/UnRARDLL.exe ,而後安裝; 2. 安裝最好選擇默認路徑,通常在 C:\Program Files (x86)\UnrarDLL\ 目錄下; 3. 而後重要的一步,就是添加環境變量,此電腦(個人電腦)右鍵,屬性,找到 高級系統設置,高級 選項卡下點擊 環境變量,在系統變量(注意不是用戶變量)中 新建,變量名輸入 UNRAR_LIB_PATH ,必須如出一轍,變量值要特別注意!若是你是64位系統,就輸入 C:\Program Files (x86)\UnrarDLL\x64\UnRAR64.dll,若是是32位系統就輸入 C:\Program Files (x86)\UnrarDLL\UnRAR.dll ,這個從unrar安裝目錄的內容也能看出來它是區分64和32位的。 4. 肯定保存環境變量後,重啓你的PyCharm,代碼不變,再運行就不會出錯了。這個時候依賴庫已經添加到系統環境中。 Linux須要本身手動編譯生成so文件,稍微麻煩一點: 1. 一樣的,先去下載源文件,不過這就不像Win那樣給你封裝好了,你須要下載的是源代碼:http://www.rarlab.com/rar/unrarsrc-5.4.5.tar.gz ,也就是RARLab官網下載列表中的 UnRAR Source,能夠下載到最新版本; 2. 下載完後解壓,獲得unrar目錄,cd unrar 後,使用 make lib 命令將會自動編譯庫文件,嘩啦啦編譯完成後,再使用 make install-lib 命令產生 libunrar.so 文件(通常在 /usr/lib 目錄下面); 3. 最後,你仍然須要設置Linux系統的環境變量,找到 /etc 目錄下的 profile 文件,固然你能夠直接使用 vim /etc/profile 命令來編輯(有WinSCP這種遠程訪問目錄的工具更方便),在 profile 文件末尾加上 export UNRAR_LIB_PATH=/usr/lib/libunrar.so ,別把我這句話的逗號加進去了。成功保存後再使用 source /etc/profile 命令使變量生效。 4. 這樣一來,再運行py文件,就不會出錯了,至少不會提示找不到unrar庫了。 友情提示:若是 make 命令用不了的,請自行安裝g++編譯器,命令:sudo apt-get install g++

上傳並解壓功能主要源碼:【tar,zip,rar三種壓縮文件】

from unrar import rarfile
import shutil

UPLOAD_FILE_TYPE = ["zip", "tar", "gztar","bztar","xztar","rar"] # 上傳功能 class Uploading(View): def get(self, request): return render(request, "uploading.html", ) def post(self, request): # 拿到上傳文件對象 file_obj = request.FILES.get("user_file") # 將上傳文件的文件名字,從右邊按'.'切割一次,返回值是列表[文件名,類型] filename, suffix = file_obj.name.rsplit(".", maxsplit=1) # 校驗上傳文件類型,不匹配的類型返回錯誤提示 if suffix not in UPLOAD_FILE_TYPE: return HttpResponse("上傳文件格式不正確") # 拼接獲得上傳文件的全路徑,而且統一上傳文件放在upload_file文件夾中 file_name = os.path.join(file_dir, file_obj.name) # 新建一個和上傳文件同名的文件 with open(file_name, "wb") as f: # 從上傳文件對象一點一點讀取數據,避免過大文件溢出內存 for chunk in file_obj.chunks(): f.write(chunk) # 對上傳的文件作處理 upload_path = os.path.join(file_dir, "files") # 解壓文件至指定文件夾 if suffix == "rar": # 讀取rar文件 rar = rarfile.RarFile(file_name) os.chdir(upload_path) # 經過索引獲取壓縮文件中的文件 rar.extractall() else: shutil.unpack_archive(file_name, extract_dir=upload_path) # getFile(upload_path) # 初始化總行數和單個文件信息屬性 totalline = 0 fileinfo_list = [] # 遍歷解壓後的文件列表,統計單個文件的行數並彙總 for filelist in filelists: fileinfo_list.append(countLine(filelist)[0]) totalline = totalline + countLine(filelist)[1] # 解壓壓縮文件,並獲取代碼行數屬性 file_info = fileinfo_list total_line = totalline # 單個文件進行文件對象實例化,文件名,文件大小,代碼行數 models.FileObj.objects.create( fileName=file_obj.name, fileSize=file_obj.size, fileMsg=file_info, fileLineCount=total_line ) return redirect("/upload_file/")

補:上述代碼中的遍歷文件和讀取代碼行數源碼:

import platform
import os
# 獲取當前項目運行的系統類型,返回字符串Windows,linux等
sys_str = platform.system()


# 定義全局變量,存儲上傳解壓後的文件列表
filelists = []

# 指定想要統計的文件類型
whitelist = ['py']


# 遍歷文件, 遞歸遍歷文件夾中的全部
def getFile(basedir):
    global filelists
    for parent, dirnames, filenames in os.walk(basedir):
        # for dirname in dirnames:
        #    getFile(os.path.join(parent,dirname)) #遞歸
        # MAC環境下略過__MACOSX文件夾
        if "__MACOSX" in dirnames:
            pop_index = dirnames.index("__MACOSX")
            dirnames.pop(pop_index)
        for filename in filenames:
            ext = filename.split('.')[-1]
            # 只統計指定的文件類型,略過一些log和cache文件
            if ext in whitelist:
                filelists.append(os.path.join(parent, filename))


# 統計一個文件的行數
def countLine(fname):
    count = 0
    single_quotes_flag = False
    double_quotes_flag = False
    with open(fname, 'rb') as f:
        for file_line in f:
            file_line = file_line.strip()
            # print(file_line)
            # 空行
            if file_line == b'':
                pass

            # 註釋 # 開頭
            elif file_line.startswith(b'#'):
                pass

            # 註釋 單引號 ''' 開頭
            elif file_line.startswith(b"'''") and not single_quotes_flag:
                single_quotes_flag = True
            # 註釋 中間 和 ''' 結尾
            elif single_quotes_flag == True:
                if file_line.endswith(b"'''"):
                    single_quotes_flag = False

            # 註釋 雙引號 """ 開頭
            elif file_line.startswith(b'"""') and not double_quotes_flag:
                double_quotes_flag = True
            # 註釋 中間 和 """  結尾
            elif double_quotes_flag == True:
                if (file_line.endswith(b'"""')):
                    double_quotes_flag = False

            # 代碼
            else:
                count += 1

        # 單個文件行數
        # print(fname, '----count:', count)
        # return count
        if sys_str == "Windows":
            fileinfo = str(fname.split('\\')[-1] + ",count:----" + str(count))
        else:
            fileinfo = str(fname.split('/')[-1] + ",count:----" + str(count))
        return fileinfo, count

4、Django調試工具:debug_toolbar

介紹

django-debug-toolbar 是一組可配置的面板,可顯示有關當前請求/響應的各類調試信息,並在單擊時顯示有關面板內容的更多詳細信息。

github地址

文檔地址

 

安裝

pip3 install django-debug-toolbar

配置

1. settings.py中

將 debug_toolbar 添加到 INSTALL_APPS 中

INSTALLED_APPS = [
    …
    'debug_toolbar',
]

2. urls.py中

from django.conf import settings
from django.conf.urls import include, url


# django 調試工具路由
if settings.DEBUG:
    import debug_toolbar
    urlpatterns = [
        url(r'__debug__/',include(debug_toolbar.urls)),
    ] + urlpatterns

3. settings.py中

在中間件中加入DebugToolbarMiddleware

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    #
    'debug_toolbar.middleware.DebugToolbarMiddleware',# django 調試工具
    #
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

4. 若是是本機調試,還在將127.0.0.1加入 INTERNAL_IPS

在settings.py中加入如下配置項:

# django調試工具配置項:
INTERNAL_IPS = ['127.0.0.1', ] # 本機調試

5.  配置jQuery的URL

django-debug-toolbar 默認使用的是Google的地址,默認配置以下:

JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js'

國內用不了的話能夠在settings.py中配置一下,例如(我這裏特地選用了和原做者相同版本的jQuery):

# 若是在Django項目中使用了jquery的話就能夠直接將這一項置爲空,那麼django-debug-toolbar 就會使用你項目中用到的jquery:
DEBUG_TOOLBAR_CONFIG = {
    # "JQUERY_URL": '',
    "JQUERY_URL": '//cdn.bootcss.com/jquery/2.2.4/jquery.min.js',
}

使用

訪問具體路徑的時候在頁面右側有各項配置面板,點擊便可查看各類調試信息。

 

 

 

(續)

相關文章
相關標籤/搜索