Django提高

在上一篇文章中我們說(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è)如下:

  1. CharField:存儲(chǔ)字符數(shù)據(jù)(如字符串)的字段。max_length 參數(shù)指定最多可存儲(chǔ)的字符
    數(shù)。

  2. IntegerField:存儲(chǔ)整數(shù)。

  3. DateField:存儲(chǔ) Python datetime.date 對(duì)象

  4. ForeignKey:用于建立一對(duì)多關(guān)系。

  5. OneToOneField:用于建立一對(duì)一關(guān)系。

  6. 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的配置

  1. 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ā)

  1. 安裝:Debug-Tool-Bar
pip install django-debug-toolbar

  1. 配置文件中添加APP
'debug_toolbar',


  1. 配置文件中添加中間鍵
'debug_toolbar.middleware.DebugToolbarMiddleware',


  1. 配置文件中配置前端效果:
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,
}


  1. 映射文件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>


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 項(xiàng)目部署到阿里云(nginx+uwsgi)上后,靜態(tài)文件加載沒(méi)有問(wèn)題。但是在本地,使用開(kāi)發(fā)服務(wù)器,卻始終加載不成功...
    蘭山小亭閱讀 5,733評(píng)論 0 9
  • PythonWeb框架要點(diǎn)、Django介紹、工程搭建、配置、靜態(tài)文件與路由 1.Python Web 框架要點(diǎn) ...
    Cestine閱讀 1,917評(píng)論 0 6
  • 處理靜態(tài)文件,尤其是在開(kāi)發(fā)時(shí),是一件很頭疼的事情。在這篇文章中,我們將會(huì)討論一些設(shè)置,目錄結(jié)構(gòu)和他們之間的相互影響...
    51reboot閱讀 1,776評(píng)論 0 1
  • Django 準(zhǔn)備 “虛擬環(huán)境為什么需要虛擬環(huán)境:到目前位置,我們所有的第三方包安裝都是直接通過(guò) pip inst...
    33jubi閱讀 1,391評(píng)論 0 5
  • 點(diǎn)我查看本文集的說(shuō)明及目錄。 本項(xiàng)目相關(guān)內(nèi)容包括: 實(shí)現(xiàn)過(guò)程: CH7 創(chuàng)建在線商店 CH8 管理支付和訂單 CH...
    學(xué)以致用123閱讀 2,427評(píng)論 1 6

友情鏈接更多精彩內(nèi)容