I need to see the complete query you’re using. You’re likely missing (or have an extra) paren.
responses = Count('response')
greens = Count('response__answer', filter=Q(response__answer__answer='Green'))
project_list = Project.objects.annotate(
response_count = responses,
green_count = greens,
fundamental_green = Case(
When(response_count=0, then=Value('null'),
default=Cast('green_count', output_field=CharField())
)
),
)
And the precise (and complete) message being presented?
Internal Server Error: /
Traceback (most recent call last):
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "D:\AzDoProjects\WebApp\app\apps\views.py", line 700, in dashboard_view
project_list = Project.objects.annotate(
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\query.py", line 1091, in annotate
return self._annotate(args, kwargs, select=True)
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\query.py", line 1130, in _annotate
clone.query.add_annotation(
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\sql\query.py", line 1039, in add_annotation
annotation = annotation.resolve_expression(self, allow_joins=True, reuse=None,
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\expressions.py", line 1045, in resolve_expression
c.cases[pos] = case.resolve_expression(query, allow_joins, reuse, summarize, for_save)
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\expressions.py", line 981, in resolve_expression
c.condition = c.condition.resolve_expression(query, allow_joins, reuse, summarize, False)
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\query_utils.py", line 102, in resolve_expression
clause, joins = query._add_q(
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\sql\query.py", line 1412, in _add_q
child_clause, needed_inner = self.build_filter(
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\sql\query.py", line 1286, in build_filter
lookups, parts, reffed_expression = self.solve_lookup_type(arg)
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\sql\query.py", line 1112, in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
File "d:\AzDoProjects\WebApp\venv\lib\site-packages\django\db\models\sql\query.py", line 1539, in names_to_path
raise FieldError("Cannot resolve keyword '%s' into field. "
django.core.exceptions.FieldError: Cannot resolve keyword 'default' into field. Choices are: ckeditor_classic, evaluation, event, founderdeveloper, fundamentals, green_count, id, marketing, otherelements, project_category, project_description, project_developers, project_investors, project_name, project_platform, project_stage, project_type, project_website, response, response2, response_count, secondaryelements
Yep, misplaced paren. (Oops, bad copy on my part.)
See Conditional Expressions | Django documentation | Django
I think it should be:
fundamental_green = Case(
When(response_count=0, then=Value('null')),
default=Cast('green_count', output_field=CharField())
),
(Winging it at the moment. Looks right, but no guarantees)
Thats fixed it. Sorry Ken. I should have spotted that.
Thanks again.
Would you be able to explain the Cast
function? I get Case
which i think is a test case. But i dont think i really understand Cast
in this line
default=Cast('green_count', output_field=CharField())
So if fundamental_green
is null
why default
Cast
is this just saying the default type if the test case is null then the result is a Charfield
?
Django requires the output of an attribute in a queryset to be of one “type”. (Character, Integer, Boolean, Date, etc). Most of the time, Django can figure out what that type should be, based upon the parameters and values being used.
In this case, you’re not consistent.
You’ve specified that if there are no responses, you want fundamental_green
to contain the character string “null”.
If responses is not 0 - which is every other case, hence the “default” value - you want to return the value of green_count
.
However, the green_count
annotation being created is an integer. In order to put green_count
into a character string field, you must tell PostgreSQL to convert that integer to a character string. That is what the Cast
function does.