由于分页前的循环 Django paginator 需要太多时间。我怎么解决这个问题?
Due to a loop before pagination Django paginator takes too much time. How can I solve this problem?
我被要求映射对象客户。我试图在循环之前进行分页,但我不知道该怎么做,因为我认为您需要在创建时将所有数据传递给分页器。
这是我的看法
我认为问题在于,当我调用函数“get_customer_view_data”时,它会在该函数内运行循环,我相信每次我在分页器上更改页面时都会发生这种情况,从而导致延迟
class CustomersView(AdminStaffRequiredMixin, TemplateView):
template_name = 'customers/tables.html'
def get(self, request, activeCustumers, *args, **kwargs):
controller = CustomerViewController()
date1 = request.GET.get('date1', 1)
date2 = request.GET.get('date2', 1)
customer_view_data = controller.get_customer_view_data(activeCustumers, date1, date2)
page = request.GET.get('page', 1)
paginator = Paginator(customer_view_data, 10)
try:
customers_data = paginator.page(page)
except PageNotAnInteger:
customers_data = paginator.page(1)
except EmptyPage:
customers_data = paginator.page(paginator.num_pages)
context = {'object_list': customers_data, 'num': len(customer_view_data)}
return render(request, self.template_name, context)
这是我映射数据的控制器:
class CustomerViewController(object):
def get_customer_view_data(self, get_active_custumers,date1,date2):
data = []
dates = self.set_dates(date1, date2)
if get_active_custumers == 1:
obj = Organization.objects.filter(organizationmainapp__application__appinfoforstore__status=2,
deleted=False,
status=True, to_deleted=False)
else:
obj = Organization.objects.all()
for o in obj:
customer_view_data = Customer()
customer_view_data.Organization_id = o.id
customer_view_data.Organization_name = o.name
try:
customer_view_data.monthly_price_plan = o.organizationmainapp.application.applicationselectedplan.price_plan.monthly_price
except Exception as e:
print(e)
try:
if o.organizationmainapp.application.applicationselectedplan.price_plan.transaction_percent_price is not None:
customer_view_data.commission = o.organizationmainapp.application.applicationselectedplan.price_plan.transaction_percent_price
else:
customer_view_data.commission = o.organizationmainapp.application.applicationselectedplan.price_plan.transaction_fixed_price
except Exception as e:
print(e)
try:
customer_view_data.App_name = o.organizationmainapp.application.appinfoforstore.store_name
except Exception as e:
print(e)
try:
customer_view_data.plan = o.organizationmainapp.application.applicationselectedplan.plan_name_stamp
except Exception as e:
print(e)
try:
customer_view_data.Total_last_Month_sales = self.get_total_sales(o.id,dates['start_date'],dates['end_date'])['total']
except Exception as e:
print(e)
try:
customer_view_data.Total_last_Month_sales_without_shipping_cost = \
self.get_total_sales(o.id, dates['start_date'], dates['end_date'])['total_without_shipping_cost']
except Exception as e:
print(e)
try:
customer_view_data.Main_mail = o.organizationmainapp.application.user.email
except Exception as e:
print(e)
data.append(customer_view_data)
return data
分页器不需要所有数据..它只需要知道会有多少行数据。您的查询集(在您的代码中,您称其为 obj
,但更清晰、通用的名称是 qs
或 queryset
)。可以直接传递给 Paginator()
并且它将在您的 QuerySet 上调用 count()
以查明将选择多少行。
我说 将被 选中,因为分页器不会从数据库中获取所有数据以对其进行计数..它只是要求数据库进行计数并且得到一个数字.. 比实际获取数据快得多的操作。
然后分页器仅获取显示当前页面所需的行。
站在你的立场上我会做的就是彻底消灭你的CustomerViewController
。 CustomerView
class 本身就是您的控制器。我会将创建和过滤查询集的代码直接放入视图中,然后将组织每一行数据的代码放入 Organization
class.
的方法中
然后,将查询集传递给Paginator
。
当您在模板中显示每个 Organization 实例时,调用(从模板内部)returns 您需要的数据的方法。这样您实际上就不会触及您不会在该页面上显示的任何行。
避免接触查询集,只需将其传递给分页器,然后使用分页器。例如.. 不要在您正在做的查询集上调用 len()
。因为查询集不是列表..它不包含任何数据直到你开始迭代它,或者直到你做了某些事情,例如,如果你从它构造一个列表,或对其调用 len()
.. 然后您将触发数据库查询并加载数据。您不希望在进行分页时发生这种情况。
对不起
我就是这样解决问题的。首先,我创建分页器,然后映射数据。出于分页目的,我还将“organization_data”传递给上下文。这不是实际代码,而是类似这样的代码:
我的观点
class CustomersView(AdminStaffRequiredMixin, TemplateView):
template_name = 'customers/tables.html'
def get(self, request, *args, **kwargs):
controller = CustomerViewController()
organizations = controller.get_customer_view_data()
page = request.GET.get('page', 1)
paginator = Paginator(organizations, 15)
try:
organization_data = paginator.page(page)
except PageNotAnInteger:
organization_data = paginator.page(1)
except EmptyPage:
organization_data = paginator.page(paginator.num_pages)
customers_data = controller.map_view_data(organization_data.object_list)
# loop over each organization and return customers data
context = {'object_list': customers_data, 'organization': organization_data}
return render(request, self.template_name, context)
我被要求映射对象客户。我试图在循环之前进行分页,但我不知道该怎么做,因为我认为您需要在创建时将所有数据传递给分页器。
这是我的看法
我认为问题在于,当我调用函数“get_customer_view_data”时,它会在该函数内运行循环,我相信每次我在分页器上更改页面时都会发生这种情况,从而导致延迟
class CustomersView(AdminStaffRequiredMixin, TemplateView):
template_name = 'customers/tables.html'
def get(self, request, activeCustumers, *args, **kwargs):
controller = CustomerViewController()
date1 = request.GET.get('date1', 1)
date2 = request.GET.get('date2', 1)
customer_view_data = controller.get_customer_view_data(activeCustumers, date1, date2)
page = request.GET.get('page', 1)
paginator = Paginator(customer_view_data, 10)
try:
customers_data = paginator.page(page)
except PageNotAnInteger:
customers_data = paginator.page(1)
except EmptyPage:
customers_data = paginator.page(paginator.num_pages)
context = {'object_list': customers_data, 'num': len(customer_view_data)}
return render(request, self.template_name, context)
这是我映射数据的控制器:
class CustomerViewController(object):
def get_customer_view_data(self, get_active_custumers,date1,date2):
data = []
dates = self.set_dates(date1, date2)
if get_active_custumers == 1:
obj = Organization.objects.filter(organizationmainapp__application__appinfoforstore__status=2,
deleted=False,
status=True, to_deleted=False)
else:
obj = Organization.objects.all()
for o in obj:
customer_view_data = Customer()
customer_view_data.Organization_id = o.id
customer_view_data.Organization_name = o.name
try:
customer_view_data.monthly_price_plan = o.organizationmainapp.application.applicationselectedplan.price_plan.monthly_price
except Exception as e:
print(e)
try:
if o.organizationmainapp.application.applicationselectedplan.price_plan.transaction_percent_price is not None:
customer_view_data.commission = o.organizationmainapp.application.applicationselectedplan.price_plan.transaction_percent_price
else:
customer_view_data.commission = o.organizationmainapp.application.applicationselectedplan.price_plan.transaction_fixed_price
except Exception as e:
print(e)
try:
customer_view_data.App_name = o.organizationmainapp.application.appinfoforstore.store_name
except Exception as e:
print(e)
try:
customer_view_data.plan = o.organizationmainapp.application.applicationselectedplan.plan_name_stamp
except Exception as e:
print(e)
try:
customer_view_data.Total_last_Month_sales = self.get_total_sales(o.id,dates['start_date'],dates['end_date'])['total']
except Exception as e:
print(e)
try:
customer_view_data.Total_last_Month_sales_without_shipping_cost = \
self.get_total_sales(o.id, dates['start_date'], dates['end_date'])['total_without_shipping_cost']
except Exception as e:
print(e)
try:
customer_view_data.Main_mail = o.organizationmainapp.application.user.email
except Exception as e:
print(e)
data.append(customer_view_data)
return data
分页器不需要所有数据..它只需要知道会有多少行数据。您的查询集(在您的代码中,您称其为 obj
,但更清晰、通用的名称是 qs
或 queryset
)。可以直接传递给 Paginator()
并且它将在您的 QuerySet 上调用 count()
以查明将选择多少行。
我说 将被 选中,因为分页器不会从数据库中获取所有数据以对其进行计数..它只是要求数据库进行计数并且得到一个数字.. 比实际获取数据快得多的操作。
然后分页器仅获取显示当前页面所需的行。
站在你的立场上我会做的就是彻底消灭你的CustomerViewController
。 CustomerView
class 本身就是您的控制器。我会将创建和过滤查询集的代码直接放入视图中,然后将组织每一行数据的代码放入 Organization
class.
然后,将查询集传递给Paginator
。
当您在模板中显示每个 Organization 实例时,调用(从模板内部)returns 您需要的数据的方法。这样您实际上就不会触及您不会在该页面上显示的任何行。
避免接触查询集,只需将其传递给分页器,然后使用分页器。例如.. 不要在您正在做的查询集上调用 len()
。因为查询集不是列表..它不包含任何数据直到你开始迭代它,或者直到你做了某些事情,例如,如果你从它构造一个列表,或对其调用 len()
.. 然后您将触发数据库查询并加载数据。您不希望在进行分页时发生这种情况。
对不起
我就是这样解决问题的。首先,我创建分页器,然后映射数据。出于分页目的,我还将“organization_data”传递给上下文。这不是实际代码,而是类似这样的代码:
我的观点
class CustomersView(AdminStaffRequiredMixin, TemplateView):
template_name = 'customers/tables.html'
def get(self, request, *args, **kwargs):
controller = CustomerViewController()
organizations = controller.get_customer_view_data()
page = request.GET.get('page', 1)
paginator = Paginator(organizations, 15)
try:
organization_data = paginator.page(page)
except PageNotAnInteger:
organization_data = paginator.page(1)
except EmptyPage:
organization_data = paginator.page(paginator.num_pages)
customers_data = controller.map_view_data(organization_data.object_list)
# loop over each organization and return customers data
context = {'object_list': customers_data, 'organization': organization_data}
return render(request, self.template_name, context)