产品折扣行动
有一天,我与我的一位朋友进行了对话,他在工作中使用了 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
文件。在即将到来的示例中,我们将看到如何做到这一点。