Python 在django中,访问OnetoMany关系中的数据以输出到模板的最佳方式是什么?
我在django工作,我的目标是将一个表输出到模板,该表由我所有的客户组成,相应的金额等于他们花费的总金额 我的类/模型Python 在django中,访问OnetoMany关系中的数据以输出到模板的最佳方式是什么?,python,django,django-models,django-views,django-templates,Python,Django,Django Models,Django Views,Django Templates,我在django工作,我的目标是将一个表输出到模板,该表由我所有的客户组成,相应的金额等于他们花费的总金额 我的类/模型客户和交易具有一对一的关系。每次客户进行购买时,交易都会记录为他们花费的金额(tx\u amount)。我有以下一组代码可以工作,但我认为它不是最优的,因为它在O(x*y)时间内运行,即为每个客户运行一个完整的事务循环 Q1:完成这项任务的最佳方式是什么 当我最初尝试让我的模板工作时,我使用的不是local\u customer,而是setattr(customer[x],“v
客户
和交易
具有一对一的关系。每次客户进行购买时,交易都会记录为他们花费的金额(tx\u amount
)。我有以下一组代码可以工作,但我认为它不是最优的,因为它在O(x*y)时间内运行,即为每个客户运行一个完整的事务循环
Q1:完成这项任务的最佳方式是什么
当我最初尝试让我的模板工作时,我使用的不是local\u customer
,而是setattr(customer[x],“value”,tx\u amount)
,它在django shell中工作,但在模板中不工作。我的解决方法是创建一个本地类,我将使用该类填充上下文
变量
问题2:当组合数据模型以在模板中输出时,是否有必要使用某种本地类,如下面的mylocal\u customer
实现,还是有更好的方法
伪代码如下:
models.py:
class Customers(models.Model):
name = models.CharField(max_length=70)
def __str__(self):
return self.name
class Transactions(models.Model):
customers = models.ForeignKey(Customers, on_delete=models.CASCADE)
tx_amount = models.DecimalField(max_digits=9, decimal_places=2
views.py:
class Local_Customer:
name = ""
total_spent = 0
def __str__(self, name):
self.name = name
def customer_view(request):
customer = Customers.objects.all()
customer_context = [] # list of objects we'll pass to render
for x in range(len(customer)):
local_customer = Local_Customer(customer[x].name)
customer_txs = Transactions.objects.filter(customer__name=customer[x])
for y in customer_txs:
local_customer.total_spent += y.tx_amount
customer_context.append(local_customer)
context = {'customers' : customer_context}
html_template = loader.get_template( load_template )
return HttpResponse(html_template.render(context, request))
template.html:
{% for customer in customers %}
{{customer.name}}
{{customer.total_spent}}
{% endfor %}
您可以在数据库端执行此操作:
from django.db.models import Sum
from django.shortcuts import render
def customer_view(request):
customers = Customers.objects.annotate(
total_spent=Sum('transactions__tx_amount')
)
context = {'customers' : customers}
return render(request, load_template, context)
更加优雅-谢谢!
SELECT customers.*, SUM(transactions.tx_amount) AS total_spent
FROM customers
LEFT OUTER JOIN transactions ON transactions.customers_id = customers.id
from django.db.models import Sum, Value
from django.db.models.functions import Coalesce
from django.shortcuts import render
def customer_view(request):
customers = Customers.objects.annotate(
total_spent=Coalesce(Sum('transactions__tx_amount'), Value(0))
)
context = {'customers' : customers}
return render(request, load_template, context)