Django中如何从一个函数访问另一个函数内的变量?
解决Django ListView中get_queryset访问get_context_data变量的问题
嘿,我来帮你搞定这个问题!你遇到的核心问题是全局变量完全不适合在类视图里共享请求级别的数据——因为每个请求都会实例化一个新的视图对象,而且get_queryset的执行时机通常在get_context_data之前,你用全局变量的时候,store还没被赋值就被调用了,自然会报错。
下面给你两种靠谱的解决方法,都是Django视图开发里的常规操作:
方法1:在get_queryset里直接获取store(最直接)
既然get_context_data里的store是通过URL参数store_domainKey获取的,那get_queryset里也可以直接用self.kwargs拿到这个参数,然后自己查询store。这样两个方法各自独立,不会互相依赖,逻辑也清晰:
class StoreDetailView(ListView): def get_queryset(self): # 和get_context_data里的逻辑完全一致,直接在这里获取store store = get_object_or_404(Store, domainKey=self.kwargs['store_domainKey']) print(store) # 现在不会报错了 # 这里返回你需要的查询集,比如和当前store关联的模型数据 return YourTargetModel.objects.filter(store=store) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['store'] = get_object_or_404(Store, domainKey=self.kwargs['store_domainKey']) return context
方法2:用实例属性self.store共享数据(更高效)
如果不想重复查询两次store,可以把store存到视图实例的属性里,这样get_queryset和get_context_data都能访问。更稳妥的是在dispatch方法里提前获取store——因为dispatch是视图处理请求的入口,会在get_queryset和get_context_data之前执行,确保后面的方法调用时self.store已经存在:
class StoreDetailView(ListView): def dispatch(self, request, *args, **kwargs): # 提前在这里获取store,只查一次 self.store = get_object_or_404(Store, domainKey=self.kwargs['store_domainKey']) return super().dispatch(request, *args, **kwargs) def get_queryset(self): print(self.store) # 直接访问实例属性 return YourTargetModel.objects.filter(store=self.store) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['store'] = self.store # 直接用已经获取到的store return context
为什么全局变量不行?
再啰嗦一句:全局变量是整个应用共享的,在多用户并发请求时,不同请求的store会互相覆盖,导致数据错乱,绝对不能用来存储请求级别的数据哦。
内容的提问来源于stack exchange,提问作者Jay P.
相关产品推荐
相关产品推荐

