在上一篇文章中我們說(shuō)到利用django框架中的模板(templates)文件已經(jīng)成功的讓瀏覽器顯示出了我們自己設(shè)置的內(nèi)容了,不過(guò)不得不說(shuō),盡管已經(jīng)創(chuàng)建成功,但是真的太簡(jiǎn)陋了。沒(méi)有樣式也沒(méi)有圖像裝飾。為了改變這種狀況,我們進(jìn)入下個(gè)階段,如何利用django來(lái)使頁(yè)面變得不那么簡(jiǎn)陋。
1.配置靜態(tài)文件
靜態(tài)文件包括層疊樣式表(Cascading Style Sheet,CSS)、JavaScript 和圖像。它們不是由 Web 服務(wù)器動(dòng)態(tài)生成的,而是原封不動(dòng)發(fā)給 Web 瀏覽器。因此我們可以引入他們。
首先在項(xiàng)目配置目錄中新建一個(gè)目錄,名為 static,用于存放靜態(tài)文件。確保 static 目錄與前面創(chuàng)建的 templates 目錄位于同一級(jí)??梢栽趧倓倓?chuàng)建的 static 目錄中再新建子目錄js,css,images用于存放不同的靜態(tài)文件,例如,我們?cè)趇mages目錄中存放一張圖片。然后我們要告訴 Django 這個(gè) static 目錄的路徑。為此,還要編輯配置文件 settings.py 模塊。 配置靜態(tài)資源路徑和URL前綴執(zhí)行以下代碼:
STATICFILES_DIRS =[os.path.join(BASE_DIR, 'static')]
STATIC_URL = '/static/'
STATICFILES_DIRS 兩個(gè)變量設(shè)定靜態(tài)文件在電腦中的位置;STATIC_URL 變量則指定啟動(dòng) Django 開(kāi)發(fā)服務(wù)器后通過(guò)什么 URL訪問(wèn)靜態(tài)文件。例: STATIC_URL 設(shè)為 /static/ 后,我們可以通過(guò) http://127.0.0.1:8000/static/訪問(wèn)里面的靜態(tài)內(nèi)容。前一個(gè)變量相當(dāng)于服務(wù)器端的位置,而第三個(gè)變量是客戶端訪問(wèn)靜態(tài)內(nèi)容的位置。
注意:設(shè)置 STATIC_URL 時(shí),確保 URL 的末尾有一個(gè)正斜線(例如,是 /static/,而不是
/static)。在末尾加上斜線的目的是把 URL 的根部(例如 /static/)與要伺服的靜態(tài)內(nèi)容(例如 images/rango.jpg)區(qū)分開(kāi)。
1.1在模板中引用靜態(tài)文件
我們已經(jīng)做好設(shè)置,Django 項(xiàng)目能處理靜態(tài)文件了?,F(xiàn)在可以在模板中利用靜態(tài)文件改進(jìn)外觀及
增添功能了。打開(kāi)模板中的HTML文件
<!DOCTYPE html>
{% load staticfiles %} <!-- 新增 -->
<html>
<head>
<title>Rango</title>
</head>
<body>
<h1> says...</h1>
<div>
hey there partner!
<br />
<strong>{{ boldmessage }}</strong><br />
</div>
div>
<img src="{% static "images/xxx.jpg" %}"
> <!-- 新增 -->
</div>
</body>
</html>
新增的第一行({% load staticfiles %})告訴 Django 模板引擎,我們將在模板中使用靜態(tài)文
件。這樣便可以在模板中使用 static 模板標(biāo)簽引入靜態(tài)目錄中的文件。static "images/xxx.jpg" 告訴 Django,我們想顯示靜態(tài)目錄中名為 images/xxx.jpg 的圖像。
只要想在模板中引用靜態(tài)文件,就可以使用 {% static %} 模板標(biāo)簽。下述代碼片段說(shuō)明如何
在模板中引入 JavaScript、CSS 和圖像。
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<title>首頁(yè)</title>
<!-- CSS -->
<link rel="stylesheet" href="{% static "css/base.css" %}" />
<!-- JavaScript -->
<script src="{% static "js/jquery.js" %}"></script>
</head>
<body>
<!-- 圖像 -->
<img src="{% static "images/rango.jpg" %}" alt="Picture of Rango" />
</body>
</html>
1.3媒體文件
應(yīng)用中的靜態(tài)文件可以理解為不變的文件。不過(guò),有時(shí)還要使用可變的媒體文件(media file)。這類文件可由用戶或管理員上傳,因此可能會(huì)變化。比如說(shuō),用戶的頭像就是媒體文件
首先,我們與設(shè)置靜態(tài)文件一樣創(chuàng)建一個(gè)media目錄,與templates目錄保持一致,然后創(chuàng)建子目錄images目錄用于存放文件,然后打開(kāi) Django 項(xiàng)目配置目錄中的 settings.py 模塊。與配置靜態(tài)文件一樣執(zhí)行以下代碼:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'#同樣別忘了斜線
-調(diào)整URL
讓 Django 使用 MEDIA_URL 伺服媒體內(nèi)容。打開(kāi)項(xiàng)目的urls.py 模塊,修改 urlpatterns 列表,調(diào)用 static() 函數(shù):
urlpatterns = [
...
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
此外,還要在urls.py模塊的頂部添加下述import語(yǔ)句:
from django.conf import settings
from django.conf.urls.static import static
現(xiàn)在可以通過(guò) /media/ URL 訪問(wèn) media 目錄中的媒體文件了。
小結(jié)(為了梳理自己思路)
? 首先,創(chuàng)建要使用的模板,保存到 templates 目錄中(在項(xiàng)目的 settings.py 模塊中設(shè)定)。模板中可以使用 Django 模板變量(例如 {{ variable_name }})或模板標(biāo)簽。模板變量的值在相應(yīng)的視圖中設(shè)定。
? 在應(yīng)用的 views.py 文件中找到所需的視圖,或者新建一個(gè)。
? 把視圖相關(guān)的邏輯寫(xiě)在視圖函數(shù)中。例如,從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù),存到列表中。
? 在視圖中構(gòu)建一個(gè)字典,通過(guò)模板上下文傳給模板引擎。
? 使用 render() 輔助函數(shù)生成響應(yīng)。這個(gè)函數(shù)的參數(shù)是請(qǐng)求對(duì)象、模板文件名和上下文字典。
? 如果還沒(méi)把視圖映射到 URL 上,修改項(xiàng)目的 urls.py 文件和應(yīng)用的 urls.py 文件
在網(wǎng)頁(yè)中引入靜態(tài)文件的步驟:
? 把想用的靜態(tài)文件放到項(xiàng)目的 static 目錄中。這個(gè)目錄在項(xiàng)目的 settings.py 模塊中的
STATICFILES_DIRS 列表中設(shè)定。
? 在模板中引用靜態(tài)文件。例如,圖像通過(guò) <img /> 標(biāo)簽插入 HTML 頁(yè)面。
? 記得在模板中加上 {% load staticfiles %},然后使用 {% static "<filename>" %} 標(biāo)簽引
用靜態(tài)文件。把 <filename> 替換成圖像或其他資源的路徑。只要想引用靜態(tài)文件,使用
static 模板標(biāo)簽。
在網(wǎng)頁(yè)中引入媒體文件的步驟:
? 把媒體文件放到項(xiàng)目的 media 目錄中。這個(gè)目錄由項(xiàng)目的 settings.py 模塊中的 MEDIA_ROOT
變量設(shè)定。
? 在模板中使用 {{ MEDIA_URL }} 上下文變量引用媒體文件。例如,引用上傳的圖像
cat.jpg:<img src="{{ MEDIA_URL}}cat.jpg" />。
2.模型與數(shù)據(jù)庫(kù)
在 Django 中,查詢底層數(shù)據(jù)庫(kù)這項(xiàng)操作由對(duì)象關(guān)系映射器(Object Relational Mapper,ORM)負(fù)責(zé)。在 ORM 中,存儲(chǔ)在一個(gè)數(shù)據(jù)庫(kù)表中的數(shù)據(jù)封裝為一個(gè)
模型。模型則是描述數(shù)據(jù)庫(kù)表中數(shù)據(jù)的 Python 對(duì)象。
2.1設(shè)置數(shù)據(jù)庫(kù)
安裝第三庫(kù)mysqlclient
pip insatll masqlclient
創(chuàng)建模型之前要設(shè)置數(shù)據(jù)庫(kù)。新建項(xiàng)目時(shí),Django 已經(jīng)自動(dòng)在 settings.py 模塊中添加了 DATABASES
變量,修改如下代碼:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '#數(shù)據(jù)庫(kù)名稱,最好和項(xiàng)目名字一致',
'HOST': '47.107.87.249',#數(shù)據(jù)庫(kù)地址
'PORT': 3306,
'USER': 'renwoxing', #授權(quán)用戶,最好不要root權(quán)限
'PASSWORD': 'xxx', #數(shù)據(jù)庫(kù)密碼
'CHARSET': 'utf8', #默認(rèn)編碼方式
'TIME_ZONE' : 'Asia/Chongqing', #設(shè)定時(shí)區(qū)
}
}
在 settings.py 模塊中配置好數(shù)據(jù)庫(kù)之后,開(kāi)始創(chuàng)建應(yīng)用所需要的數(shù)據(jù)模型,模型保存在應(yīng)用目錄中的models.py模塊里。
class Subject(models.Model):
''''學(xué)科類模型'''
#自增
no = models.AutoField(primary_key=True,verbose_name='編號(hào)')
name = models.CharField(max_length=20,verbose_name='名稱')
intro = models.CharField(max_length=1000,verbose_name='介紹')
is_hot = models.BooleanField(default=False,verbose_name='是否熱門')
def __str__(self): #魔法方法,生成類的字符串表示形式
return self.name
class Meta:
db_table = 'tb_subject'
verbose_name = '學(xué)科'
verbose_name_plural = '學(xué)科'
定義模型時(shí),要指定字段及其類型,并提供必須或可選的參數(shù)。Django中內(nèi)置的字段類型常用的幾個(gè)如下:
CharField:存儲(chǔ)字符數(shù)據(jù)(如字符串)的字段。max_length 參數(shù)指定最多可存儲(chǔ)的字符
數(shù)。IntegerField:存儲(chǔ)整數(shù)。
DateField:存儲(chǔ) Python datetime.date 對(duì)象
ForeignKey:用于建立一對(duì)多關(guān)系。
OneToOneField:用于建立一對(duì)一關(guān)系。
ManyToManyField:用于建立多對(duì)多關(guān)系。
2.2創(chuàng)建和遷移數(shù)據(jù)庫(kù)
首先,數(shù)據(jù)庫(kù)必須預(yù)置,即創(chuàng)建數(shù)據(jù)庫(kù)及相關(guān)的表。打開(kāi)終端輸入以下代碼:
#創(chuàng)建遷移
python manage.py makemigrations polls
#執(zhí)行遷移
python manage.py migrate
然后,創(chuàng)建一個(gè)超級(jí)用戶(superuser),用于管理數(shù)據(jù)庫(kù)。執(zhí)行下述命令:
python manage.py createsuperuser
這個(gè)超級(jí)用戶在本章后面將用于訪問(wèn) Django 管理界面。請(qǐng)根據(jù)提示輸入用戶名、電子郵件地址和密碼。
可以打開(kāi)一個(gè)admin.py用來(lái)后臺(tái)管理數(shù)據(jù)庫(kù)中創(chuàng)建的類,例如以下代碼:
class SubjectAdmin(admin.ModelAdmin):
list_display = ('no','name','intro','is_hot') #將要展示的各項(xiàng)名稱
list_display_links = ('no','name') #創(chuàng)建的軟連接
search_fields = ('name',) #創(chuàng)建克搜索字段
ordering = ('no',) #按指定字段排序 (注意此處為元祖,切勿忘記后面的逗號(hào))
#結(jié)尾
admin.site.register(Subject, SubjectAdmin)
#注冊(cè)想要在管理界面顯示的類
接下來(lái)在urls.py中創(chuàng)建映射,例如:
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
]
改好之后,重啟 Django 開(kāi)發(fā)服務(wù)器,然后再次訪問(wèn) http://127.0.0.1:8000/admin/。你可以看到類似以下頁(yè)面:

3.補(bǔ)充
3.1為用戶密碼創(chuàng)建哈希摘要(利用重寫(xiě)Model里的save方法)
創(chuàng)建一個(gè)py文件定義生成哈希摘要的函數(shù),執(zhí)行以下代碼:
import hashlib
def to_md5_hex(content):
"""生成MD5摘要"""
講內(nèi)容轉(zhuǎn)換成字節(jié)串生成哈希摘要后返回
return hashlib.md5(content.encode()).hexdigest()
在manage.py中在為用戶創(chuàng)建的類中,重寫(xiě)save方法,代碼如下:
class User(models.Model):
'''用戶(模型類)'''
no = models.AutoField(primary_key=True, verbose_name='編號(hào)')
username = models.CharField(max_length=20, unique=True,verbose_name='用戶名')
password = models.CharField(max_length=32,verbose_name='密碼')
email = models.CharField(default='', max_length=256, verbose_name='郵箱')
tel = models.CharField(max_length=11, verbose_name='手機(jī)號(hào)碼', unique=True)
reg_date = models.DateTimeField(auto_now_add=True,verbose_name='注冊(cè)日期')
last_visit = models.DateTimeField(verbose_name='最后訪問(wèn)')
def save(self):
'''商業(yè)活動(dòng)中要加鹽'''
self.password =to_md5_hex(self.password)
super().save()
class Meta:
db_table = 'tb_user'
verbose_name = '用戶'
verbose_name_plural = '用戶'
這時(shí)候打開(kāi)數(shù)據(jù)庫(kù)可以看到password已經(jīng)變成哈希摘要保存了。

3.2cookie和會(huì)話
cookie是什么?
Web 服務(wù)器收到請(qǐng)求后會(huì)返回所請(qǐng)求頁(yè)面的內(nèi)容。除了內(nèi)容之外,還會(huì)返回一些 cookie。cookie
可以理解為服務(wù)器發(fā)給客戶端的少量信息。準(zhǔn)備發(fā)送請(qǐng)求時(shí),客戶端檢查有沒(méi)有與服務(wù)器地址匹
配的 cookie,如果有,隨請(qǐng)求一起發(fā)送。服務(wù)器收到請(qǐng)求后把 cookie 放在請(qǐng)求的上下文中解釋,
然后生成合適的響應(yīng)。
會(huì)話是什么?
Web 瀏覽器(客戶端)與服務(wù)器之間的通信都借由 HTTP 協(xié)議。前面說(shuō)過(guò),HTTP 是無(wú)狀態(tài)的協(xié)議。因此,Web 瀏覽器所在的客戶端電腦每次請(qǐng)求服務(wù)器中的資源(HTTP GET)或者把資源發(fā)給服務(wù)器(HTTP POST)都要建立新的網(wǎng)絡(luò)連接(TCP 連接)。
由于客戶端和服務(wù)器之間無(wú)法建立持久連接,所以兩端的軟件都不能只依靠連接維持會(huì)話狀態(tài)。
例如,客戶端發(fā)送的每個(gè)請(qǐng)求都要指明哪個(gè)用戶在當(dāng)前電腦上已登錄 Web 應(yīng)用。這是客戶端與服務(wù)器之間的一種對(duì)話,是半永久性信息交互機(jī)制(即會(huì)話)的基礎(chǔ)。
3.2.1在Django中設(shè)置會(huì)話
session的配置
- Session對(duì)應(yīng)的中間件:django.contrib.sessions.middleware.SessionMiddleware。
2.Session引擎:
- 基于數(shù)據(jù)庫(kù)(默認(rèn)方式)
INSTALLED_APPS = [
'django.contrib.sessions',
]
- 基于緩存(推薦使用)
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'session'
- 基于Cookie(不靠譜)
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
cookie的配置
SESSION_COOKIE_NAME = 'djang_session_id'
SESSION_COOKIE_AGE = 1209600
# 如果設(shè)置為True,Cookie就是基于瀏覽器窗口的Cookie,不會(huì)持久化
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_SAVE_EVERY_REQUEST = False
SESSION_COOKIE_HTTPONLY = True
3.4配置緩存
CACHES = {
# 默認(rèn)緩存
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': [
'redis://1.2.3.4:6379/0',
],
'KEY_PREFIX': 'teamproject',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'CONNECTION_POOL_KWARGS': {
'max_connections': 1000,
},
'PASSWORD': 'yourpass',
}
},
# 頁(yè)面緩存
'page': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': [
'redis://1.2.3.4:6379/1',
],
'KEY_PREFIX': 'teamproject:page',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'CONNECTION_POOL_KWARGS': {
'max_connections': 500,
},
'PASSWORD': 'yourpass',
}
},
# 會(huì)話緩存
'session': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': [
'redis://1.2.3.4:6379/2',
],
'KEY_PREFIX': 'teamproject:session',
'TIMEOUT': 1209600,
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'CONNECTION_POOL_KWARGS': {
'max_connections': 2000,
},
'PASSWORD': 'yourpass',
}
},
# 接口數(shù)據(jù)緩存
'api': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': [
'redis://1.2.3.4:6379/3',
],
'KEY_PREFIX': 'teamproject:api',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'CONNECTION_POOL_KWARGS': {
'max_connections': 500,
},
'PASSWORD': 'yourpass',
}
},
}
#全站緩存
MIDDLEWARE_CLASSES = [
'django.middleware.cache.UpdateCacheMiddleware',
...
'django.middleware.common.CommonMiddleware',
...
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 300
CACHE_MIDDLEWARE_KEY_PREFIX = 'djang:cache'
#視圖層緩存
from django.views.decorators.cache import cache_page
from django.views.decorators.vary import vary_on_cookie
@cache_page(timeout=60 * 15, cache='page') #利用裝飾器
@vary_on_cookie
def my_view(request):
pass
from django.views.decorators.cache import cache_page
urlpatterns = [
url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
]
如你所見(jiàn),添加緩存機(jī)制只需調(diào)用一個(gè)裝飾器函數(shù)即可;在調(diào)用時(shí)需要傳參,timeout為超時(shí)時(shí)間,在固定時(shí)間后緩存自動(dòng)清除;cache選擇緩存組;
3.5配置日志
日志級(jí)別
NOTSET < DEBUG < INFO < WARNING < ERROR < FATAL
日志配置:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
# 配置日志格式化器
'formatters': {
'simple': {
'format': '%(asctime)s %(module)s.%(funcName)s: %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
},
'verbose': {
'format': '%(asctime)s %(levelname)s [%(process)d-%(threadName)s] '
'%(module)s.%(funcName)s line %(lineno)d: %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
}
},
# 配置日志過(guò)濾器
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
# 配置日志處理器
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'filters': ['require_debug_true'],
'formatter': 'simple',
},
'file1': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': 'access.log',
'when': 'W0',
'backupCount': 12,
'formatter': 'simple',
'level': 'INFO',
},
'file2': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': 'error.log',
'when': 'D',
'backupCount': 31,
'formatter': 'verbose',
'level': 'WARNING',
},
},
# 配置日志器
'loggers': {
'django': {
'handlers': ['console', 'file1', 'file2'],
'propagate': True,
'level': 'DEBUG',
},
}
}
3.6調(diào)試工具Debug模式便于開(kāi)發(fā)
- 安裝:Debug-Tool-Bar
pip install django-debug-toolbar
- 配置文件中添加APP
'debug_toolbar',
- 配置文件中添加中間鍵
'debug_toolbar.middleware.DebugToolbarMiddleware',
- 配置文件中配置前端效果:
DEBUG_TOOLBAR_CONFIG = {
# 引入jQuery庫(kù)
'JQUERY_URL': 'https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js',
# 工具欄是否折疊
'SHOW_COLLAPSED': True,
# 是否顯示工具欄
'SHOW_TOOLBAR_CALLBACK': lambda x: True,
}
- 映射文件urls.py中配置路由
if settings.DEBUG:
import debug_toolbar
urlpatterns.insert(0, path('__debug__/', include(debug_toolbar.urls)))
3.7 利用django自帶分頁(yè)器
# 導(dǎo)入分頁(yè)工具
from django.core.paginator import Paginator
# 調(diào)用分頁(yè)器函數(shù)會(huì)返回一個(gè)對(duì)象
page_obj = = Paginator(obj_list, per_page)
obj_list是需要分頁(yè)的內(nèi)容
per_page是每頁(yè)的內(nèi)容數(shù)量,一般為int類型
# 對(duì)象的使用方法
page_obj.has_previous ---> 是否存在前一頁(yè)(布爾值)
page_obj.has_next ---> 是否存在下一頁(yè)(布爾值)
page_obj.previous_page_number ---> 前一頁(yè)的頁(yè)碼(數(shù)值)
page_obj.next_page_number ---> 下一頁(yè)的頁(yè)碼(數(shù)值)
page_obj.number ---> 當(dāng)前頁(yè)的頁(yè)碼(數(shù)值)
page_obj.get_page(page) ---> ???
page_obj.page(3) ---> 訪問(wèn)指定頁(yè)面
page2.start_index() ---> 從1開(kāi)始計(jì)數(shù)的當(dāng)前頁(yè)的第一個(gè)對(duì)象
3
page2.end_index() ---> 從1開(kāi)始計(jì)數(shù)的當(dāng)前頁(yè)最后1個(gè)對(duì)象
paginator.page_range ---> 頁(yè)碼范圍(迭代對(duì)象)
paginator.num_pages ---> 頁(yè)面總數(shù)量(數(shù)值)
3.8關(guān)于 查詢的一部分語(yǔ)法
Entry.objects.all() ---> 查詢所有記錄
# 指定查詢:only
queryset = Teacher.objects.filter(subject__no=sno).only('', '', '')
# 排除查詢:defer
queryset = Teacher.objects.filter(subject__no=sno).defer('', '')
# 空值查詢:
District.objects.filter(pid__null=True)
# 條件查詢:
Entry.objects.filter(num=3) ---> 查詢num=3的數(shù)據(jù)記錄
Entry.objects.exclude(num=3) ---> 查詢num=3的數(shù)據(jù)記錄
# 使用切片的方法可以進(jìn)行范圍取值,相當(dāng)于SQL語(yǔ)句中的LIMIT和OFFSET子句
Entry.objects.all()[:5] ---> 返回前5個(gè)對(duì)象
Entry.objects.all()[5:10] ---> 返回第6個(gè)到第10個(gè)對(duì)象
# 關(guān)鍵字查詢:
1) 精確查詢: __exact (默認(rèn)就是精準(zhǔn)查詢,可以不寫(xiě))
Entry.objects.get(headline__exact="Cat bites dog")
2) 模糊查詢
__contains:是否包含
__startswith: 以指定值開(kāi)頭
__endswith:以指定值結(jié)尾
3) 空查詢
isnull:是否為null
4) 范圍查詢
in:是否包含在范圍內(nèi)
5) 比較查詢
gt、gte、lt、lte:大于、大于等于、小于、小于等于
6) 日期查詢
year、month、day、week_day、hour、minute、second:對(duì)日期時(shí)間類型的屬性進(jìn)行運(yùn)算
7) 不區(qū)分大小寫(xiě): __iexact
Entry.objects.get(name__iexact="beatles blog")
# Q對(duì)象查詢
在查詢的條件中需要組合條件時(shí)(例如兩個(gè)條件“且”或者“或”)。我們可以使用Q()查詢對(duì)象
from django.db.models import Q
Q(question__startswith='What')
可以在Q()對(duì)象的前面使用字符“~”來(lái)代表意義“非”
可以使用 “&”或者“|”還有括號(hào)來(lái)對(duì)條件進(jìn)行分組從而組合成更加復(fù)雜的查詢邏輯
Q(question__startswith='Who') | Q(question__startswith='What')
例:
queryset = Record.objects.filter(Q(car__carno__startswith=carno) | Q(car__owner__contains=carno)).select_related('car').order_by('-offend_time')[(page - 1) * size:page * size]
context['records'] = queryset
# .select_related('car') 在Q對(duì)象中car__carno已經(jīng)實(shí)現(xiàn)連表查詢,這時(shí)再用.select_related('car')語(yǔ)法連同car一起查詢
.prefetch_related('...') ---> 多對(duì)多順帶查詢
.select_related('...') ---> 一對(duì)多順帶查詢
避免1+n出現(xiàn)
3.9前端Vue的部分語(yǔ)法
1. 屬性:
1) el屬性 - 字符串,傳選擇器(一般寫(xiě)id選擇器), 將當(dāng)前創(chuàng)建的Vue對(duì)象和html中的標(biāo)簽進(jìn)行關(guān)聯(lián)
2) data屬性 - 通過(guò)對(duì)象的屬性提供數(shù)據(jù)
3) methods屬性 - 通過(guò)對(duì)象屬性提供方法
4) computed屬性 - 屬性值必須函數(shù), 函數(shù)的返回值就是使用屬性的值
5) created鉤子 - 在實(shí)例被創(chuàng)建之后被調(diào)用
2. Vue指令
1) 標(biāo)簽內(nèi)容 - {{Vue屬性名}}
2) 標(biāo)簽屬性 - v-bind:標(biāo)簽屬性 = 'Vue屬性名'
3) if語(yǔ)句 - v-if='Vue屬性名' (如果Vue屬性值是true對(duì)應(yīng)的標(biāo)簽就顯示,否則就隱藏)
4) 循環(huán)結(jié)構(gòu) - v-for = '變量 in 類型是數(shù)組的Vue屬性'
5) 雙向綁定 - v-model='Vue屬性名' (一般在表單標(biāo)簽中有效)
6) 事件綁定 - v-on:事件名
3. 補(bǔ)充
1) 可以直接在標(biāo)簽內(nèi)用 @事件名 的方法綁定事件,并直接調(diào)用事件函數(shù)
例:<button @click="prevPage()">上一頁(yè)</button>
2) 縮寫(xiě)
v-bind 縮寫(xiě)
<!-- 完整語(yǔ)法 -->
<a v-bind:href="url">...</a>
<!-- 縮寫(xiě) -->
<a :href="url">...</a>
v-on 縮寫(xiě)
<!-- 完整語(yǔ)法 -->
<a v-on:click="doSomething">...</a>
<!-- 縮寫(xiě) -->
<a @click="doSomething">...</a>