pythondjangodjango-modelsdjango-querysetdjango-managers

FieldError: Cannot resolve keyword 'get_str' into field while using @property method in values_list() in a QuerySet


I have a model named Invitation, where I have created a property method which returns the value returned by __str__() method, like below:

class Invitation(models.Model):
    def __str__(self):
        name = "Sent To: " + self.sent_to + " - Invited To: " + self.invited_to

        if self.accepted_at is not None:
            name = name + " - Accepted On: " + \
                str(self.accepted_at.date()) + " (yy-mm-dd) - At: " + str(self.accepted_at.hour) + \
                ":" + str(self.accepted_at.minute) + ":" + str(self.accepted_at.second) + \
                " (hh:mm:ss)"
        
        if self.is_canceled:
            name = name + " - CANCELED"
        elif timezone.now() > self.expiration_date:
            name = name + " - EXPIRED AT: " + str(self.expiration_date)

        return(name)

    @property
    def get_str(self):
        return self.__str__()

Now, I am trying to use this property method in QuerySet's values_list() method as below:

Invitation.objects.values_list("pk", "get_str")

But I am getting following error:

Cannot resolve keyword 'get_str' into field. Choices are: accepted_at, created_at, created_by, created_by_id, expiration_date, id, invited_to, invitee_first_name, invitee_last_name, is_canceled, secret, sent_to

Full Traceback of error is:

Traceback Switch to copy-and-paste view
/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/query.py, line 2107, in add_fields
                join_info = self.setup_joins( …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/query.py, line 1773, in setup_joins
                path, final_field, targets, rest = self.names_to_path( …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/query.py, line 1677, in names_to_path
                    raise FieldError( …
Local vars
During handling of the above exception (Cannot resolve keyword 'get_str' into field. Choices are: accepted_at, created_at, created_by, created_by_id, expiration_date, id, invited_to, invitee_first_name, invitee_last_name, is_canceled, secret, sent_to), another exception occurred:
/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py, line 55, in inner
                response = get_response(request) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/base.py, line 197, in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/base.py, line 84, in view
            return self.dispatch(request, *args, **kwargs) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/contrib/auth/mixins.py, line 73, in dispatch
        return super().dispatch(request, *args, **kwargs) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/base.py, line 119, in dispatch
        return handler(request, *args, **kwargs) …
Local vars
/app/apps/accounts/views.py, line 295, in get
        invites = Invitation.objects.get_invites_to_cancel(user) …
Local vars
/app/apps/accounts/models.py, line 551, in get_invites_to_cancel
                values_list("pk", "get_str") …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/db/models/query.py, line 980, in values_list
        clone = self._values(*_fields, **expressions) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/db/models/query.py, line 943, in _values
        clone.query.set_values(fields) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/query.py, line 2425, in set_values
        self.add_fields(field_names, True) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/db/models/sql/query.py, line 2140, in add_fields
                raise FieldError( …
Local vars

What wrong am I doing? What is the proper way to use property method? Any help would be appreciated.


Solution

  • You can annotate field to your qs containing all required fields and then call values_list on that field

    qs = Invitation.objects.annotate(
                str=Concat(F('name'), Value(' - '), F('id'), output_field=models.CharField())
            ).values_list('pk', 'str')
    

    result is:

    (14, 'zeta - 14')