Django是一個(gè)文檔很全的框架,學(xué)習(xí)的時(shí)候老是遇到一些坑,這里就順便記錄一下,以便后面使用,同時(shí)也希望本文可以幫助到其他的朋友。
操作系統(tǒng):macOS Cataline 10.15.3
Python:pyenv 安裝的 pypy3.6-7.3.0 (PyPy解釋器平均比我們平時(shí)使用的CPython快4.4倍)
Django:Django 3.0.3
macOS下Django3在連接MySQL會(huì)出一些問題,解決如下:
# 確保 pip 是最新版本$ pip install --upgrade pip# 臨時(shí)在當(dāng)前的shell環(huán)境中配置一個(gè) openssl 變量export LDFLAGS="-L/usr/local/opt/openssl/lib $LDFLAGS"export CPPFLAGS="-I/usr/local/opt/openssl/include $CPPFLAGS"$ pip install mysqlclient
在models.py
中含有ImageField
圖片類型的時(shí)候,如果pillow
沒有安裝好的話 會(huì)報(bào)錯(cuò):
image = models.ImageField(upload_to='avatar/%Y/%m', verbose_name='頭像', max_length=100)
解決方法是macOS下安裝配置好zlib
即可:
# 安裝 zlib$ brew install zlib# 鏈接 zlib 會(huì)提示$ brew link zlib --forceWarning: Refusing to link macOS-provided software: zlibFor compilers to find zlib you may need to set: export LDFLAGS="-L/usr/local/opt/zlib/lib" export CPPFLAGS="-I/usr/local/opt/zlib/include"
根據(jù)上述提示,進(jìn)行如下操作:
# 臨時(shí)在當(dāng)前的shell環(huán)境中配置一個(gè) zlib 變量export LDFLAGS="-L/usr/local/opt/zlib/lib"export CPPFLAGS="-I/usr/local/opt/zlib/include"$ pip install pillow
模板目錄 Python 命令行創(chuàng)建的 Django 項(xiàng)目默認(rèn)是沒有自動(dòng)生成這個(gè)目錄的,首先項(xiàng)目目錄下新建templates
文件夾,然后配置一下settings:
settings.py
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # 將 templates 設(shè)置為模板目錄 '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', ], }, },]
該目錄存放一些css js 之類的靜態(tài)文件,也得手動(dòng)到 settings.py 添加配置一下:
settings.py
STATIC_URL = '/static/'STATICFILES_DIRS = [(os.path.join(BASE_DIR, 'static'))]
當(dāng)項(xiàng)目下的app太多的時(shí)候,項(xiàng)目的目錄結(jié)構(gòu)看上去就會(huì)比較混亂,一個(gè)解決辦法就是將項(xiàng)目下的所有app都放到一個(gè)apps的文件夾中,首先項(xiàng)目下新建apps
文件夾,接著手動(dòng)到 settings.py 添加配置一下:
settings.py
import osimport sysBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))sys.path.insert(0, os.path.join(BASE_DIR, 'apps')) # 將 apps 文件夾添加到 BASE_DIR中
media文件夾用來存放用戶上傳的圖片資料等,首先配置下settings.py
settings.py
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.template.context_processors.media', # 添加 media 模板 ], }, },]
接著配置 media 根目錄變量:
settings.py
MEDIA_URL = '/media/'MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
配置好之后在 urls.py 里面配置下 media 的路由規(guī)則:
urls.py
from django.urls import path, re_pathfrom django.views.static import servefrom project.settings import MEDIA_ROOTurlpatterns = [ path('admin/', admin.site.urls), # 配置 media 的處理 re_path('media/(?P<path>.*)', serve, {'document_root': MEDIA_ROOT}, name='org_list'), ]
下面看一下 簡(jiǎn)單的 引用 meida 中圖片文件的實(shí)例:
models.py
class CourseOrg(models.Model): ... image = models.ImageField(upload_to='org/%Y/%m', verbose_name='logo', max_length=100) ...
前端調(diào)用顯示 media 里的文件
<img width="200" height="120" class="scrollLoading" data-url="{{ MEDIA_URL }}{{ course_org.image }}"/>
項(xiàng)目地址:https://github.com/mbi/django-simple-captcha
$ pip install django-simple-captcha
安裝好之后,在settings.py
引用即可:
settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'captcha', # 引用驗(yàn)證碼插件]
引用完成后,更新下數(shù)據(jù)庫的信息,因?yàn)檫@個(gè)驗(yàn)證碼信息是存放在本地?cái)?shù)據(jù)庫中的:
$ python manage.py makemigrations$ python manage.py migrate
數(shù)據(jù)庫更新成功后可以在數(shù)據(jù)庫下看到 captcha_captchastore
表名,接著得配置下驗(yàn)證碼的url路由規(guī)則:
urls.py
urlpatterns = [ path('admin/', admin.site.urls), path('captcha/', include('captcha.urls')),]
Form表單中定義如下:
forms.py
from django import formsfrom captcha.fields import CaptchaFieldclass RegisterForm(forms.Form): email = forms.EmailField(required=True) password = forms.CharField(required=True, min_length=5) captcha = CaptchaField(error_messages={'invalid': '驗(yàn)證碼錯(cuò)誤'})
Views里面實(shí)例化這個(gè)表單類:
views.py
class RegisterView(View): def get(self, request): register_form = RegisterForm() return render(request, 'register.html', { 'register_form': register_form })
views.py里面 返回了register_form
到前端,接著前端可以直接調(diào)用 驗(yàn)證碼:
<div class="form-group marb8 captcha1"><label>驗(yàn)證碼</label>{{ register_form.captcha }}</div>
項(xiàng)目地址:https://github.com/jamespacileo/django-pure-pagination
$ pip install django-pure-pagination
安裝好之后,在settings.py
引用即可:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'pure_pagination',]
views里面的基本用法:
views.py
from pure_pagination import Paginator, EmptyPage, PageNotAnIntegerclass OrgView(View): """ 課程機(jī)構(gòu)列表功能顯示 """ def get(self, request): # 課程機(jī)構(gòu) all_orgs = CourseOrg.objects.all() # 官方提倡的寫法 try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 # 將數(shù)據(jù)庫中 查詢的 all_orgs 分頁 每頁顯示5個(gè) p = Paginator(all_orgs, 5, request=request) orgs = p.page(page) return render(request, 'org-list.html', { 'all_orgs': orgs, # 分頁的結(jié)果傳給前端 })
前端分頁的引用:
<div class="pageturn"><ul class="pagelist"><!-- 判斷是是否有上一頁 --> {% if all_orgs.has_previous %} <li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">上一頁</a></li> {% endif %}<!-- 顯示中間頁數(shù) 和 高亮 當(dāng)前頁 --> {% for page in all_orgs.pages %} {% if page %} {% ifequal page all_orgs.number %} <li class="active"><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li> {% else %} <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li> {% endifequal %} {% else %} <li class="none"><a href="">...</a> </li> {% endif %} {% endfor %}<!-- 判斷是是否有下一頁 --> {% if all_orgs.has_next %} <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">下一頁</a></li> {% endif %}</ul></div>
最后的分頁效果如下:
項(xiàng)目地址:https://github.com/django-import-export/django-import-export
$ pip install django-import-export
安裝好之后,在settings.py
引用即可:
settings.py
INSTALLED_APPS = [ 'import_export', # 引用導(dǎo)入導(dǎo)出插件 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',]
接著可以直接在Django Admin后臺(tái)引用:
admin.py
from import_export.admin import ImportExportActionModelAdmin@admin.register(CourseOrg)class CourseOrgAdmin(ImportExportActionModelAdmin): list_display = ['name', 'image_data', 'address'] search_fields = ['name', 'city', 'address', 'desc'] list_filter = ['city', 'add_time']
最后配合Simple UI的效果如下:
在urls.py 里面添加 如下即可:
admin.site.site_header = '后臺(tái)管理'admin.site.site_title = 'Django 后臺(tái)管理'
核心原理就是 在引用 這個(gè)模塊的文件里面添加配置即可生效:
from django.contrib import admin
最后效果如下:
Django Admin 的列表中圖片只顯示 url 地址,卻不能直接顯示出來:
解決方法就是重寫Django Admin 后臺(tái)圖片的顯示。
models.py
from django.utils.html import format_htmlclass CourseOrg(models.Model): image = models.ImageField(upload_to='org/%Y/%m', verbose_name='logo', max_length=100) # 定義 image_data 將 url 手動(dòng) 通過 img 表情顯示出來 def image_data(self): return format_html( '<img src="{}" width="200px" height="90px"/>', self.image.url, ) # 設(shè)置標(biāo)題 image_data.short_description = '圖片'
admin.py
from django.contrib import admin@admin.register(CourseOrg)class CourseOrgAdmin(admin.ModelAdmin): # 顯示里面 傳入 我們自定義的 image_data list_display = ['name', 'image_data', 'address'] search_fields = ['name', 'city', 'address', 'desc'] list_filter = ['city', 'add_time'] # 設(shè)置該列不可編輯 readonly_fields = ('image_data',)
最后顯示效果如下:
聯(lián)系客服