我有两个具有一对多关系的模型。数据库中每个模型类都有多个对象。我创建了一个自定义查询集,它迭代所有父对象和所有子对象,然后将它们加载到字典中,然后将其用作查询集。
我的问题是如何优化nested_query_loop函数以减少访问数据库的次数?我尝试合并 select_lated() 和 prefetch_lated() 但永远无法让它工作,因为我需要将其作为向后关系进行查询,以便让每个子对象与其父对象在一起。
问题的第二部分:我尝试通过创建parent_object和child_object参数使函数可重用,但这不起作用,因为我必须使用ObjectName_set()方法,该方法要求对象名称小写。此外,ObjectName_set() 有一个下划线,因此 child_object_set() 甚至 ChildObject_set() 无法识别并引发错误。在我的例子中,子对象模型名称的首字母大写。所以我的问题是:有什么方法可以将函数内的模型名称全部小写吗?或者解决这个问题的唯一方法是将源中的模型名称更改为小写?或者甚至更好的问题:是否有一个我没有看到的 django 类或函数可以为我完成所有这一切?我不想重新发明轮子并让事情变得更糟。
'''蟒蛇
class MasterListView(ListView):
template_name = 'passdown/master_list.html'
context_object_name = 'entries'
def nested_query_loop(self):
object_list = []
all_objects = PassDown.objects.all() #queryset containing all passdown objects
for object in all_objects:
object_list.append(object.pk) #list containing all passdown primary keys (object_list)
query_dict={}
for i in object_list:
temp_obj = PassDown.objects.get(pk=i) #ith passdown object itself
sub_object_pk_list=[]
all_i_entries = temp_obj.entry_set.all() #queryset containing all entry objects of i
for j in all_i_entries:
sub_object_pk_list.append(j.pk) #list containing all entry primary keys of i (sub_object_pk_list)
sub_object_list = []
for k in sub_object_pk_list:
sub_object_list.append(all_i_entries.get(pk=k)) #list containing all ith entry objects (sub_object_list)
query_dict.__setitem__(temp_obj, sub_object_list)
return query_dict
def get_queryset(self):
queryset = PassDown.objects.all()
return queryset
def get_context_data(self, **kwargs):
context = super(MasterListView, self).get_context_data(**kwargs)
queryset = self.nested_query_loop()
context.update({
"parent_child_dict": queryset
})
return context
'''
'''蟒蛇
class PassDown(models.Model):
shiftList = [("Days", "Days"),
("Nights", "Nights"),
("Mids", "Mids")]
shift = models.CharField(max_length=10, choices=shiftList)
date_time = models.DateTimeField(default=timezone.now)
notes = models.TextField()
entered_by = models.ForeignKey(User, on_delete=models.DO_NOTHING)
#entry = models.ForeignKey(Entry, on_delete=models.DO_NOTHING)
def __str__(self):
return f"{self.shift} {self.date_time}"
class Entry(models.Model):
modex = models.IntegerField()
discrepancy = models.CharField(max_length=50)
text_body = models.TextField()
passdown = models.ForeignKey(PassDown, on_delete=models.CASCADE, default=PassDown.objects.last)
def __str__(self):
return f"{self.modex} {self.discrepancy} {self.passdown.date_time}"
'''
我不明白你的代码和下面的代码之间的区别
def nested_query_loop(self):
passdowns = PassDown.objects.all()
return {passdown: passdown.entry_set.all() for passdown in passdowns}
如果我没有错过任何事情的话。您可以使用简单的预取将查询数量减少到两次。
def nested_query_loop(self):
passdowns = PassDown.objects.prefetch_related("entry_set")
return {passdown: passdown.entry_set.all() for passdown in passdowns}
但是我不知道你的字典可以用来做什么,因为你可以在模板中调用 related_manager 。
这是经典列表视图的样子
class MasterListView(ListView):
model PassDown
template_name = 'passdown/master_list.html'
context_object_name = 'passdowns'
def get_queryset(self):
# Only define for performance reasons
queryset = super().get_queryset()
queryset = queryset.prefetch("entry_set")
return queryset
{{ for passdown in passdowns }}
# Render your passdown object
{{ for entry in passdown.entry_set.all }}
# Render your related entry