Django Rest Framework 创建查询集分组依据
Django Rest Framework create Queryset Group By
你好我会写这一行sql查询:
select rating, date, count(rating) as "Count" from analyse
where wkn='x' and date between 'x' and 'y' group by rating
我的模型Class是这个
class Analyse(models.Model):
date = models.DateField(blank=True, null=True)
week_day = models.CharField(blank=True, max_length=500)
location = models.CharField(blank=True, max_length=500)
old_rating = models.CharField(blank=True, max_length=500)
rating = models.CharField(blank=True, max_length=500)
Serializer 和 View 是这样的
class RatingSerializer(serializers.Serializer):
rating = serializers.ReadOnlyField()
total = serializers.ReadOnlyField()
date = serializers.DateField()#format='%Y'
class CompaniesChartsView(generics.ListAPIView):
http_method_names = ['get']
permission_classes = (AllowAny,)
serializer_class = RatingSerializer
def get(self, request, wkn, format=None):
self.query = self.request.GET.get('chart')
end = datetime.date.today()
#start = datetime.date(datetime.date.today().year-1, 1, 1)
start = datetime.date(datetime.date.today().year-1,
datetime.date.today().month, datetime.date.today().day)
try:
if self.query == "ratings":
queryset = Analyse.objects.values('date', 'rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
serializer = RatingSerializer(queryset, many=True)
print(serializer.data)
print(connection.queries)
return Response(serializer.data)
else:
return Response("Bad request",
status=status.HTTP_400_BAD_REQUEST)
except:
pass
Django 生成但是这个查询。这不是我想要的。
'SELECT "statistic_app_analyse"."date",
"statistic_app_analyse"."rating",
COUNT("statistic_app_analyse"."rating") AS "total" FROM
"statistic_app_analyse" WHERE ("statistic_app_analyse"."wkn" =
\'840400\' AND "statistic_app_analyse"."date" BETWEEN \'2017-12-20\'
AND \'2018-12-20\') GROUP BY "statistic_app_analyse"."date",
"statistic_app_analyse"."rating"'
Django 添加日期字段作为分组依据。
当我将查询更改为:
queryset = Analyse.objects.values('rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
然后工作,但缺少日期。
当我将 Django 查询更改为一行时 sql 查询
queryset = Analyse.objects.raw("SELECT db.wkn,
db.rating, db.date, COUNT (*) as 'Count' FROM
analyse as db WHERE db.wkn='578580' and db.date like
'2018%'")
queryset = list(queryset)
serializer = RatingSerializer(queryset, many=True)
return Response(serializer.data)
然后我得到一个错误
Internal Server Error: /api/companies/840400/charts/
Traceback (most recent call last):
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args,
**callback_kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/rest_framework/views.py", line 497, in dispatch
self.response = self.finalize_response(request, response, *args,
**kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/rest_framework/views.py", line 412, in finalize_response
% type(response)
AssertionError: Expected a `Response`, `HttpResponse` or
HttpStreamingResponse` to be returned from the view, but received a
<class 'NoneType'>`
[20/Dec/2018 12:05:18] "GET /api/companies/840400/charts/?
chart=ratings
HTTP/1.1" 500 85144
感谢您的帮助
您的直接问题是视图从 get()
返回 None
。这可以通过修改 try/except.
来解决
def get(self, request, wkn, format=None):
self.query = self.request.GET.get('chart')
end = datetime.date.today()
#start = datetime.date(datetime.date.today().year-1, 1, 1)
start = datetime.date(datetime.date.today().year-1,
datetime.date.today().month, datetime.date.today().day)
try:
if self.query == "ratings":
queryset = Analyse.objects.values('date', 'rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
serializer = RatingSerializer(queryset, many=True)
print(serializer.data)
print(connection.queries)
return Response(serializer.data)
except:
pass
return Response("Bad request",
status=status.HTTP_400_BAD_REQUEST)
但是,捕获空白异常并传递它是一种糟糕的做法。如果你要传递一个异常,你应该知道可能会引发什么异常,此时你应该捕获那些特定的异常,而不是简单地 Exception
。它的另一部分是它隐藏了您的代码出现的问题。所以我建议使用:
def get(self, request, wkn, format=None):
self.query = self.request.GET.get('chart')
end = datetime.date.today()
#start = datetime.date(datetime.date.today().year-1, 1, 1)
start = datetime.date(datetime.date.today().year-1,
datetime.date.today().month, datetime.date.today().day)
if self.query == "ratings":
queryset = Analyse.objects.values('date', 'rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
serializer = RatingSerializer(queryset, many=True)
print(serializer.data)
print(connection.queries)
return Response(serializer.data)
return Response("Bad request",
status=status.HTTP_400_BAD_REQUEST)
In order to get the date to get the date removed from the GROUP BY
clause,try removed from the argument list to .values()
:
queryset = Analyse.objects.values('rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
你好我会写这一行sql查询:
select rating, date, count(rating) as "Count" from analyse
where wkn='x' and date between 'x' and 'y' group by rating
我的模型Class是这个
class Analyse(models.Model):
date = models.DateField(blank=True, null=True)
week_day = models.CharField(blank=True, max_length=500)
location = models.CharField(blank=True, max_length=500)
old_rating = models.CharField(blank=True, max_length=500)
rating = models.CharField(blank=True, max_length=500)
Serializer 和 View 是这样的
class RatingSerializer(serializers.Serializer):
rating = serializers.ReadOnlyField()
total = serializers.ReadOnlyField()
date = serializers.DateField()#format='%Y'
class CompaniesChartsView(generics.ListAPIView):
http_method_names = ['get']
permission_classes = (AllowAny,)
serializer_class = RatingSerializer
def get(self, request, wkn, format=None):
self.query = self.request.GET.get('chart')
end = datetime.date.today()
#start = datetime.date(datetime.date.today().year-1, 1, 1)
start = datetime.date(datetime.date.today().year-1,
datetime.date.today().month, datetime.date.today().day)
try:
if self.query == "ratings":
queryset = Analyse.objects.values('date', 'rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
serializer = RatingSerializer(queryset, many=True)
print(serializer.data)
print(connection.queries)
return Response(serializer.data)
else:
return Response("Bad request",
status=status.HTTP_400_BAD_REQUEST)
except:
pass
Django 生成但是这个查询。这不是我想要的。
'SELECT "statistic_app_analyse"."date",
"statistic_app_analyse"."rating",
COUNT("statistic_app_analyse"."rating") AS "total" FROM
"statistic_app_analyse" WHERE ("statistic_app_analyse"."wkn" =
\'840400\' AND "statistic_app_analyse"."date" BETWEEN \'2017-12-20\'
AND \'2018-12-20\') GROUP BY "statistic_app_analyse"."date",
"statistic_app_analyse"."rating"'
Django 添加日期字段作为分组依据。
当我将查询更改为:
queryset = Analyse.objects.values('rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
然后工作,但缺少日期。
当我将 Django 查询更改为一行时 sql 查询
queryset = Analyse.objects.raw("SELECT db.wkn,
db.rating, db.date, COUNT (*) as 'Count' FROM
analyse as db WHERE db.wkn='578580' and db.date like
'2018%'")
queryset = list(queryset)
serializer = RatingSerializer(queryset, many=True)
return Response(serializer.data)
然后我得到一个错误
Internal Server Error: /api/companies/840400/charts/
Traceback (most recent call last):
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args,
**callback_kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/rest_framework/views.py", line 497, in dispatch
self.response = self.finalize_response(request, response, *args,
**kwargs)
File "/home/hendrik/PycharmProjects/automatic-information-extraction-
from-stock-analysis/venv/lib/python3.5/site-
packages/rest_framework/views.py", line 412, in finalize_response
% type(response)
AssertionError: Expected a `Response`, `HttpResponse` or
HttpStreamingResponse` to be returned from the view, but received a
<class 'NoneType'>`
[20/Dec/2018 12:05:18] "GET /api/companies/840400/charts/?
chart=ratings
HTTP/1.1" 500 85144
感谢您的帮助
您的直接问题是视图从 get()
返回 None
。这可以通过修改 try/except.
def get(self, request, wkn, format=None):
self.query = self.request.GET.get('chart')
end = datetime.date.today()
#start = datetime.date(datetime.date.today().year-1, 1, 1)
start = datetime.date(datetime.date.today().year-1,
datetime.date.today().month, datetime.date.today().day)
try:
if self.query == "ratings":
queryset = Analyse.objects.values('date', 'rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
serializer = RatingSerializer(queryset, many=True)
print(serializer.data)
print(connection.queries)
return Response(serializer.data)
except:
pass
return Response("Bad request",
status=status.HTTP_400_BAD_REQUEST)
但是,捕获空白异常并传递它是一种糟糕的做法。如果你要传递一个异常,你应该知道可能会引发什么异常,此时你应该捕获那些特定的异常,而不是简单地 Exception
。它的另一部分是它隐藏了您的代码出现的问题。所以我建议使用:
def get(self, request, wkn, format=None):
self.query = self.request.GET.get('chart')
end = datetime.date.today()
#start = datetime.date(datetime.date.today().year-1, 1, 1)
start = datetime.date(datetime.date.today().year-1,
datetime.date.today().month, datetime.date.today().day)
if self.query == "ratings":
queryset = Analyse.objects.values('date', 'rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))
serializer = RatingSerializer(queryset, many=True)
print(serializer.data)
print(connection.queries)
return Response(serializer.data)
return Response("Bad request",
status=status.HTTP_400_BAD_REQUEST)
In order to get the date to get the date removed from the GROUP BY
clause,try removed from the argument list to .values()
:
queryset = Analyse.objects.values('rating')
.filter(
Q(wkn=wkn) &
Q(date__range=([start, end])))
.annotate(total=Count('rating'))