產品折扣行動
有一天,我與我的一位朋友進行了對話,他在工作中使用了 Laravel PHP 框架。當我告訴他 Django 有自己的全包式 HTML CRUD 系統時,為了與資料庫互動,稱為 Django admin ,他的眼睛突然出現了! 他告訴我:“ 我花了幾個月的時間為我當前的網路應用程式構建一個 Admin 介面,而你說你擁有所有這些,而無需編寫一行程式碼? ”。我回答“ Yeap! ”
Django 管理是一個強大的功能的 Django 提供很多東西。其中一個是行動 。
但是什麼行動是什麼?
假設你有一個模型,並且你已經新增了一些條目(可能數百個,也許數千個)。現在,你希望在不使用控制檯(python manage.py shell
)的情況下將規則操作應用於其中至少一個 :
# python manage.py shell (interactive console)
from math import ceil
from my_app.models import Product
DISCOUNT = 10 # percentage
for product in Product.objects.filter(is_active=True):
""" Set discount to ALL products that are flagged as active """
multiplier = DISCOUNT / 100. # DISCOUNT / 100 in python 3 (without dot)
old_price = product.price
new_price = ceil(old_price - (old_price * multiplier)) # seller wins :)
product.price = new_price
product.save(update_fields=['price'])
你是否注意到我們將折扣應用於所有產品。如果我們想將這個邏輯應用於特定的邏輯怎麼辦?或者,如果我們想手動輸入折扣值,然後將此值應用於某些產品?所有這些都通過 Django 管理員! 你走在正確的軌道上。Django 行動 FTW。讓我們看一個完整的例子。
基礎:
- Python 3.4.3
- Django 1.10
- SQLite(內建 Python,無需額外的安裝設定)
該模型:
- 代表我們的電子商店的產品
- 產品的價格是整數(不是小數)
目標:
- 能夠通過 Django Admin 介面對一個或多個產品條目應用固定折扣。
設定(app,model 和 Django admin)
假設你已經啟動了一個專案 ,請轉到 manage.py
所在的目錄並建立一個名為 stock
的應用程式,方法是輸入:
python manage.py createapp stock
Django 會自動為你建立一個目錄結構。去編輯 models.py
檔案並新增:
# models.py
from django.db import models
class Product(models.Model):
name = models.CharField('Product name', max_length=100) # required field
price = models.PositiveIntegerField('Product price')
def __str__(self): # __unicode__ in Python 2
return self.name
我們的 Product
模型已經建立,但資料庫中還沒有。為了使遷移工作,我們的應用程式必須包含在 INSTALLED_APPS
列表中。
編輯你的 settings.py
檔案並在 INSTALLED_APPS
列表下新增:
# settings.py
INSTALLED_APPS = [
# ... previous Django apps
'stock.apps.StockConfig',
]
現在執行:
python manage.py makemigrations
python manage.py migrate
在 migrate
命令之後,你的資料庫現在有一個名為 product
的表,其中包含三列 id
,name
和 price
。到現在為止還挺好!
如果你沒有更改 ROOT_URLCONF 檔案中的任何內容( 通常位於資料夾 <your_project_name>/<your_project_name>/
中),則指向 Django 管理站點的 URL 應為:
# urls.py
urlpatterns = [
# ... other URLs
url(r'^admin/', admin.site.urls),
]
到目前為止,我們還沒有看到有關 Django 管理操作的任何具體內容。最後一步,在 stock/admin.py
檔案中新增:
# admin.py
from django.contrib import admin
from .models import Product
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
pass
好。設定完成。只是為了確保一切正常,執行:
python manage.py runserver
並使用你最喜歡的瀏覽器訪問頁面 127.0.0.1:8000/admin/
。你應該看到閃亮光鮮,了不起 Django 管理頁面,它允許你 ç reate- [R ead- U pdate- d elete 你 Product
典範! 如果有任何機會,上面的頁面會詢問你的使用者名稱/密碼而你沒有任何問題。你還沒有建立一個 User
來登入管理員。只需執行:
python manage.py createsuperuser
輸入你的姓名,電子郵件,使用者名稱和密碼(兩次),你就完成了。
生成一些假冒產品
到目前為止,我們已經建立了模型但沒有條目(沒有產品)。我們需要一些條目來闡明 Django 管理員行動的力量。
我們將創造 100 種產品並與之合作。但是,我們不會手動按下 ADD 按鈕並輸入 name
和 price
,而是編寫一個指令碼來為我們完成工作。
執行 python manage.py shell
並輸入以下內容:
# python manage.py shell
from stock.models import Product
for i in range(1, 101):
p = Product.objects.create(name='Product %s' % i, price=i)
上面的 for
迴圈建立(這意味著資料儲存在資料庫中)100 個產品(條目)名稱為 Product 1
,Product 2
,… Product 100
和價格 1
,2
,…,100
。
要通過 Django 管理頁面檢視這些產品,請再次訪問 127.0.0.1:8000/admin/
並單擊 Products
連結:
享受你自動生成的 100 種產品:
這被稱為 Django 的 change list
頁面。現在,為了讓它看起來更漂亮,編輯你的 stock/admin.py
檔案並輸入:
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ('name', 'price')
現在,點選重新整理,你應該會看到顯示價格的第二列。
唷! 最後的行動
回顧一下,我們有模型,我們有條目。接下來,我們要建立一個操作,一旦選擇它將對所選產品進行 30%的折扣。
你是否注意到 change list
頁面頂部有一個選擇框,標籤為 Action
?Django 會自動在每個執行 D elete 操作的條目上新增預設操作。
Django 管理操作是作為簡單函式編寫的。讓我們潛入。編輯 stock/admin.py
檔案並新增以下內容:
# admin.py
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ('name', 'price')
actions = ['discount_30']
def discount_30(self, request, queryset):
from math import ceil
discount = 30 # percentage
for product in queryset:
""" Set a discount of 30% to selected products """
multiplier = discount / 100. # discount / 100 in python 3
old_price = product.price
new_price = ceil(old_price - (old_price * multiplier))
product.price = new_price
product.save(update_fields=['price'])
discount_30.short_description = 'Set 30%% discount'
這裡有幾點需要注意:
ProductAdmin
類有一個額外的屬性(actions
),它是一個字串列表(每個字串是代表該動作的函式的名稱)。- 動作功能是
ProductAdmin
類的一種方法。它以ModelAdmin
例項(self
,因為這是一種方法),HTTP request
物件和queryset
(所選物件 - 條目 - 產品的列表)為引數。 - 最後一行是一個函式屬性(
short_description
),它在 actions 選擇框中設定顯示的名稱(為了轉義單個%,有一個 double%)。
在函式操作中,我們迭代每個產品(被選中),我們將其值設定減少 30%。然後我們使用引數 update_fields
呼叫 save()
方法,以強制對資料庫中 update_fields
列表中包含的欄位(而不是模型的所有欄位上的 UPDATE)執行 UPDATE,這是出於效能原因(不是效能)在這個例子中獲得,只有 2 列,但你明白了。)
現在,在 change list
頁面點選重新整理,你應該看到你的行動在 delete
之下。繼續選擇一些產品(使用左上角核取方塊左側的每個或所有產品的核取方塊),選擇 Set 30% discount
操作並單擊 Go
按鈕。而已!
當然,在大多數情況下這不是很方便,因為此操作不允許你輸入不同的折扣金額。每次要應用其他折扣時,都必須編輯 admin.py
檔案。在即將到來的示例中,我們將看到如何做到這一點。