Reputation: 8897
I build web application with Django REST Framework. There is one simple view, which return reference Information with db fields.
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
)
It works fine, but when I add new object to one the resources querysets. Nothing happens, it show old queries.
I tried printed RESOURSES
in my module, it printed once and other get requests don't trigger it.
Then I move RESOURSES
directly in class ResourceApiView
and it's behavior same like when RESOURSES
where in module.
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):
...
It work fine only when I put RESOURSES
in get
method.
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,
......
}
But why is it happening? Why I can't evaluate queries from class attributes for each method call?
Upvotes: 1
Views: 92
Reputation: 20102
this is more related to python than to django. Let's say you hava file lib.py
def say_hello():
print "hello"
GREETINGS = {
"hello": say_hello()
}
now go to another python file (or the shell) and just import your lib.py
, you'll print "hello" to the console because when you import the file It starts resolving the code inside so it's creating the GREETINGS variable (RESOURCES in your case) and calling the say_hello() method, for you it's executing the query. However python is smart enough that if you import the file again he'll remember that you just imported it before so it wont load the module again, cause it already has the module reference saved.
Your query is beeing executed once when the view was first loaded, and reimporting the view wont make the reference change
The same for placing RESOURCES as a class attribute. The code was executed when the class was imported (again you can test it by creating a class on the lib.py
example)
hope this clarifies :) but maybe the docs explains it better https://docs.python.org/2/tutorial/modules.html
Note:
I think that the .data
on the serializer is actually executing the query. Without it your query and the serializer would just be stored as reference, because the ORM is lazy. Change your RESOURCES to improve the performance of your endpoint because right now if you request one single resource (e.g. 'authors) its still executing ALL the queries ('authors', 'genres', etc)
Upvotes: 2