了解Django中的VIew评估

时间:2016-08-12 12:15:56

标签: python django django-rest-framework

我使用Django REST Framework构建Web应用程序。有一个简单的视图,它返回带有db字段的参考信息 resources.py:

RESOURCES = {
    'genres': GenreSerializer(Genre.objects.all(), many=True).data,
    'authors': AuthorSerializer(Author.objects.all(), many=True).data,
    ......
    }


class ResourceApiView(views.APIView):

    def get(self, request):
        params = request.query_params
        response_dict = {}
        if params:
        # Return RESOURSES based on query params
            for i in params:
                q = RESOURCES.get(i)
                if q:
                    response_dict[i] = q
        else:
        # Return all RESOURSES
            response_dict = RESOURCES
        return Response(response_dict,
                        status=status.HTTP_200_OK
                        )

它工作正常,但是当我将新对象添加到资源查询集时。什么都没发生,它显示旧查询 我在我的模块中尝试打印RESOURSES,打印一次,其他请求不会触发它 然后我直接在课程RESOURSES中移动ResourceApiView,其行为与模块中的RESOURSES时的行为相同。

class ResourceApiView(views.APIView):

    RESOURCES = {
        'genres': GenreSerializer(Genre.objects.all(), many=True).data,
        'authors': AuthorSerializer(Author.objects.all(), many=True).data,
        ......
        }

    def get(self, request):
        ...

只有在RESOURSES方法中添加get时才能正常工作。

class ResourceApiView(views.APIView):

    def get(self, request):
        RESOURCES = {
            'genres': GenreSerializer(Genre.objects.all(), many=True).data,
            'authors': AuthorSerializer(Author.objects.all(), many=True).data,
             ......
             }

但为什么会这样呢?为什么我无法为每个方法调用评估类属性的查询?

1 个答案:

答案 0 :(得分:2)

这与python比django更相关。让我们说你hava文件lib.py

def say_hello():
    print "hello"

GREETINGS = {
    "hello": say_hello()
}

现在转到另一个python文件(或shell),然后导入你的lib.py,你打印"你好"到控制台,因为当你导入文件时它开始解析里面的代码,所以它创建了GREETINGS变量(在你的情况下为RESOURCES)并调用say_hello()方法,为你执行查询。然而,python足够聪明,如果你再次导入文件,他会记得你之前刚刚导入它,因此它不会再次加载模块,因为它已经保存了模块参考。

您的查询在首次加载视图时执行一次,重新导入视图不会使参考更改

将RESOURCES作为类属性放置相同。导入类时执行代码(同样可以通过在lib.py示例上创建类来测试它)

希望这可以澄清:)但是文档可能会更好地解释https://docs.python.org/2/tutorial/modules.html

注意: 我认为序列化程序上的.data实际上是在执行查询。如果没有它,您的查询和序列化程序将仅作为参考存储,因为ORM是惰性的。更改资源以提高端点的性能,因为如果您请求一个单一资源(例如作者),它仍在执行所有查询(' authors',' genres&#39 ;等等)