0

I don't have a lot of Python experience and can't figure out how to use a list of strings with the SearchVector functionality described here. I'm using Django 1.10 with PostgreSQL 9.6 and have verified that this works if I write the fields in manually.

This function is from a class based view and its purpose is to receive a string from a form, then do a full text search against all CharFields in all Models within MyApp, then return the results (planning on using itertools to combine multiple QuerySets once I get this working). I don't want to hardcode the fields because we will be adding new objects and new fields regularly - its a sort of corporate middleware app where I am not able to master the data.

def get_queryset(self):
    searchTargets = defaultdict(list)
    myModels = (obj for obj in apps.get_models()
                if obj._meta.label.startswith('myapp')
                and not obj._meta.label == 'myapp.ConfigItem')
    for thing in myModels:
        fieldNames = (x.name for x in thing._meta.fields)
        for thisField in fieldNames:
            if thing._meta.get_field(thisField).get_internal_type() == 'CharField':
                searchTargets[thing._meta.object_name].append(thisField)
    user_query=self.request.GET['user_query']
    for key in searchTargets.iterkeys():
        targetClass=class_for_name('myapp.models',key)
        results = targetClass.objects.annotate(
            search=SearchVector(searchTargets[key]),
            ).filter(search=user_query)
        #only a single QuerySet will be returned. 
        return results

I've tried ','.join(MyList) but of course that just makes one big string.

Community
  • 1
  • 1
womblerone
  • 552
  • 7
  • 18

1 Answers1

0

Expand the list using * and SearchVector will happily search multiple fields.

results = targetClass.objects.annotate(
    search=SearchVector(*searchTargets[key]),
    ).filter(search=user_query)
womblerone
  • 552
  • 7
  • 18