无法将关键字“ get_album_detail”解析为字段

时间:2020-10-23 21:28:51

标签: django django-models django-views django-orm django-managers

我试图创建一个可以获取歌手姓名和歌曲名称的搜索字段,但遇到一条错误消息:“无法将关键字'get_full_album_detail'解析为字段”。一旦我尝试从“ 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 个答案:

答案 0 :(得分:2)

get_album_detail不是字段,它是一个属性。因此,这意味着它是在Django / Python层确定的,因此数据库无法对其进行过滤,因为数据库不知道Django / Python层。

您可以使用.annotate(…) [Django-doc]来“派生”查询中的字段,然后对其进行过滤。在这种情况下,我们可以使用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