我有一个在Django中构建的应用程序.该应用程序允许企业管理其日常运营,并具有人力资源管理、销售、销售点、会计等功能.
为了让企业能够为其产品附加折扣,我创建了一个Discount
模型:
class Discount(CommonField):
name = models.CharField(max_length=255, blank=True, null=True)
discount = models.DecimalField(max_digits=15, decimal_places=2)
discount_type = models.CharField(max_length=255, choices=DISCOUNT_TYPE_CHOICES, blank=True, null=True)
discounted_products_count = models.PositiveSmallIntegerField(default=0)
start_date = models.DateTimeField(blank=True, null=True)
expiry_date = models.DateTimeField(blank=True, null=True)
status = models.CharField(max_length=255, default="inactive", choices=DISCOUNT_STATUS)
objects = DiscountModelManager()
折扣有start date和expiry date,这两个已包含在模型中,它们还有一个状态字段,用于确定状态是expired、active还是inactive.
我面临的挑战之一与我应该在什么时候更新折扣状态有关.为了克服这一挑战,我创建了一个Model Manager,以便在中心位置放置更新状态的逻辑;
class DiscountModelManager(TenantAwareManager):
def get_queryset(self):
queryset = super().get_queryset()
self.change_promo_code_if_end_date_extended(queryset)
self.activate_discount_if_start_date_reached(queryset)
self.expire_discount_if_expiry_date_reached(queryset)
return super().get_queryset()
def change_promo_code_if_end_date_extended(self, queryset):
"""
Activates promo codes if expiry_date has been extended and the status is expired.
"""
queryset.filter(expiry_date__gte=timezone.now(), status="expired").update(status="active")
def activate_discount_if_start_date_reached(self, queryset):
"""
Activates promo codes if start_date has been reached and the status is inactive.
"""
queryset.filter(start_date__lte=timezone.now(), status="inactive").update(status="active")
def expire_discount_if_expiry_date_reached(self, queryset):
queryset.filter(expiry_date__lte=timezone.now()).update(status="expired")
目前我有四种观点来处理折扣:
-
Dicount List View
:其中列出了属于该特定业务的所有折扣(101). -
Detail Discount View
:其中显示折扣的详细视图. -
Edit Discount View
:用户可以在详细信息视图中查看折扣后编辑折扣 -
Point of Sale View
:发生促销并且在 checkout 时可能使用折扣.
代码运行良好,除了我还有一个问题..
如果我们查看折扣列表查看:
class DiscountListView(LoginRequiredMixin, View):
def get(self, request):
business_id = current_business_id()
discounts = Discount.objects.filter(business__business_id=business_id)
paginator = Paginator(discounts, 25)
page_number = request.GET.get("page")
page = paginator.get_page(page_number)
context = {
"table_headers": HTMLTemplateTags().table_headers["discounts"],
"page": page,
"search_query": search_query,
"paginator": paginator,
}
return render(request, "pages/sales/discounts/discount_list.html", context)
您可以看到我们有一个queryset
,其中我们正在获取属于当前业务的所有折扣
discounts = Discount.objects.filter(business__business_id=business_id)
在此查询集完成之前,将调用DiscountModelManager
并更新状态.目前,这不是一个大问题,因为我们刚刚开始,但一旦我们有数百万个折扣,那么这种方法就根本不是最佳的,因为属于特定企业的所有折扣都会更新.
有没有更好、更有效的方法来解决这个问题?