Cannot resolve keyword 'get_album_detail' into field

621 views Asked by At

Am trying to create a search field that can get the artist name and the name of the song, but am getting an error saying "Cannot resolve keyword 'get_full_album_detail' into field." once i try to query from 'get_album_detail'.

 class Artist(models.Model):
    user            =   models.OneToOneField(User, on_delete=models.CASCADE)
    username        =   models.CharField(max_length=50, null=True, unique=True)



class Album(models.Model):
        artist      =   models.ForeignKey(Artist, on_delete=models.CASCADE)
        name        =   models.CharField(max_length=120)

    @property
    def get_album_detail(self):
        return str(self.artist.username) + " - " + str(self.name)



   ### CUSTOM MODEL MANAGER
class SongQuerySet(models.QuerySet):
    def search(self, query = None):
        qs = self
        if query is not None:
            or_lookup = (Q(get_album_detail__icontains=query)|
                Q(slug__icontains=query)
                #Q(artist__user__icontains=query)
                )
            qs = qs.filter(or_lookup).distinct()
        return qs

## SEARCH VIEW
class AlbumSearch(ListView):
    template_name   =   'search/song_search.html'
    paginate_by     =   15  

    def get_queryset(self):
        request =   self.request
        query = request.GET.get('q', None)
        if query is not None:
            song_result   =   Song.objects.search(query=query)
            return song_result
1

There are 1 answers

7
willeM_ Van Onsem On

get_album_detail is not a field, it is a property. This thus means that it is determined at the Django/Python layer, and thus the database can not filter on it, since the Django/Python layer is not known by the database.

You can use .annotate(…) [Django-doc] to "derive" the field in the query and then filter on it. In this case, we can use Concat [Django-doc]:

from django.db.models import Value
from django.db.models.functions import Concat

# …

def search(self, query = None):
    qs = self
    if query is not None:
        or_lookup = (
            Q(album_detail__icontains=query) |
            Q(slug__icontains=query)    
        )
        qs = qs.annotate(
            album_detail=Concat('artist__username', Value(' - '), 'name')
        ).filter(or_lookup).distinct()
    return qs