Python生成器可以在Django视图中使用吗? 问题:

Python生成器可以在Django视图中使用吗? 问题:,python,django,django-views,django-orm,Python,Django,Django Views,Django Orm,本质上,我希望每次调用视图时都从数据库返回一个唯一的结果,直到用完唯一的对象并重新开始。我在想一个简单而优雅的解决方案是使用一个发电机来处理这个问题。这是可能的吗?如果可能的话,如何从ORM中提取值 注: 我认为会话或使用Memento之类的设计模式可能是一种解决方案,但我真的很好奇Python生成器是否以及如何在这种环境中使用。由于Django是同步wsgi,您必须独立处理每个请求,您的Python环境随时都可能被终止或切换到其他环境 不过,如果您没有恐惧感,只需要一个进程,就可以创建一个包含

本质上,我希望每次调用视图时都从数据库返回一个唯一的结果,直到用完唯一的对象并重新开始。我在想一个简单而优雅的解决方案是使用一个发电机来处理这个问题。这是可能的吗?如果可能的话,如何从ORM中提取值

注:
我认为会话或使用Memento之类的设计模式可能是一种解决方案,但我真的很好奇Python生成器是否以及如何在这种环境中使用。

由于Django是同步wsgi,您必须独立处理每个请求,您的Python环境随时都可能被终止或切换到其他环境

不过,如果您没有恐惧感,只需要一个进程,就可以创建一个包含会话ID和迭代器的文件范围字典,每次都要使用它

from django.shortcuts import render
from collections import defaultdict
import uuid

def iterator():
    for item in DatabaseTable.objects.all():
    yield item

sessions_current_iterators = defaultdict(iterator)

def my_view(request):
    id = request.session.get("iterator_id", None)
    if id is None:
        request.session["iterator_id"] = str(uuid.uuid4())
    try:
        return render(request, "item_template.html", {"item": next(sessions_current_iterators)}
    except StopIteration:
        request.session.pop("iterator_id")
        return render(request, "end_template.html", {})
但是:千万不要在生产环境中使用它


生成器在计算请求时可以很好地减少内存消耗,也可以很好地用于tornado web服务,但很明显,django不应该在本地变量中的请求之间共享数据。

您可以在可以使用return的地方使用yield,因为它们是python而不是django。这里唯一需要注意的是,对每个请求调用相同的函数;因此,收益率之后的延续可能服务于另一个客户,而不是您想要的客户。但是,您可以通过在此处使用更高级别的函数生成器来解决此问题。基本上,函数将有一个生成器字典,由从请求派生的唯一键索引。每次调用函数时,检查字典中是否已经存在请求的条目。如果没有,则为该请求添加一个新函数。然后为给定的请求调用生成器,确保存储生成器生成或返回的内容。为了将字典保存在内存中,现在让main函数产生存储值。最后,为了避免每次调用main函数时都清除字典,通过将字典初始化为空字典来启动函数体;然后将其他所有内容包装在一个无限while循环中。这将确保主功能(也是生成器)永远不会真正退出。当第一次调用时,字典被初始化;然后时间开始了。在此期间,如果给定请求的条目不存在,函数将在字典中创建并存储生成器。然后,该函数为请求调用生成器,并生成生成器在while底部返回或生成的任何内容。当再次被召唤时;主功能在while的顶部恢复。代码是这样的:

def main_func(request, *args) :
    funcs = {} 
    while True:
        request_key = make_key(request)
        If request_key not in funcs.keys():
            def generator_func():
                # your generator code here... 
                # remember to delete the func item in funcs before returning... 
            funcs[request_key]  = generator_func
        yield funcs[request_key] () 

    def make_key(request):
        # quick and dirty impl
        return str(request.session) 

这完全取决于您希望如何使用它们。请记住,在正常生产中,您有多个进程正在运行。这使得维持一个全球国家变得困难。您可能想看看如何使用缓存来处理这类事情。