我有两个相关的模型(1-n)。在父模型中,我正在子模型上执行很多操作。对于每个操作,我都会调用:
ItensOrder.objects.filter(order=self.pk)
在作为父类的Order类内部,我多次使用了children对象,如下所示:
def total(self):
itens = ItensOrder.objects.filter(order=self.pk)
valor = sum(Counter(item.price * item.quantity for item in itens))
return str(valor)
def details(self):
itens = ItensOrder.objects.filter(order=self.pk)
return format_html_join('\n', "{} ({} x {} = {})<br/>",
((item.item.name,str(item.quantity),item.price,str(item.price * item.quantity)) for item in itens))
仅一次加载相关对象的最佳方法是什么,因此我可以避免每次需要相关对象时都访问数据库。
我一直在父模型上尝试过这个:
def __init__(self, *args, **kwargs):
if self.pk is not None:
self.itens = ItensOrder.objects.filter(order=self.pk)
else:
self.itens = None
但这是错误的。...
任何人都可以帮助!!
答案 0 :(得分:0)
您可以使用ForeignKey
字段的related_name来访问相关的子对象
order = Order.objects.get(id=1)
itens = order.itensorder_set.all()
默认情况下,此反向关系属性将是小写的型号名称,后跟“ _set”,您可以通过在外键上设置related_name
来更改此设置
您可以使用prefetch_related
order = Order.objects.prefetch_related('itensorder_set').get(id=1)
order.itensorder_set.all() # This can be called multiple times but will not hit the database
以您的情况
class Order(models.Model):
def total(self):
valor = sum(Counter(item.price * item.quantity for item in self.itensorder_set.all()))
return str(valor)
def details(self):
return format_html_join('\n', "{} ({} x {} = {})<br/>",
((item.item.name,str(item.quantity),item.price,str(item.price * item.quantity)) for item in self.itensorder_set.all()))
并在模型管理员中覆盖get_queryset
def get_queryset(self, request):
return super().get_queryset(request).prefetch_related('itensorder_set')
答案 1 :(得分:0)
您可以在函数内使用select_related
def total(self):
itens = ItensOrder.objects.select_related('order').filter(order=self)
valor = sum(Counter(item.price * item.quantity for item in itens))
return str(valor)
def details(self):
itens = ItensOrder.objects.select_related('order').filter(order=self)
return format_html_join('\n', "{} ({} x {} = {})<br/>",
((item.item.name,str(item.quantity),item.price,str(item.price * item.quantity)) for item in itens))