关于django 1.3的多搜索查询

时间:2016-12-02 11:49:24

标签: python django

我正在尝试在我的搜索过滤器上实现多个列,但我总是遇到查询错误:

这是我的models.py:

class Livro(models.Model):
codigo = models.AutoField(primary_key=True)
nome = models.CharField("Nome", max_length=50)
autor = models.CharField("Autor", max_length=50)
edicao = models.CharField("Edição", max_length=30)
disciplina = models.ForeignKey(Disciplina)
tipo = models.CharField("Tipo", max_length=20, choices = Choices.tipo)
ano = models.CharField("Ano", max_length=30, choices = Choices.ano)
situacao = models.CharField("Situação", max_length=30, choices = Choices.situacao, default = Choices.situacao[0][1], blank = True, null = True)

def __unicode__(self):
    return self.nome

这是我的views.py:

def consultar_livro(request):
    if request.method == 'POST':
        nome = request.POST['nome']
        livro =    Livro.objects.filter(nome__icontains=nome).order_by('nome')    
    return render_to_response('consultar_livro.html', locals(),      context_instance = RequestContext(request))

而不仅仅是名字我还需要使用situacao,disciplina,tipo e ano。我该怎么办?我尝试过只是像我一样添加名字和使用Q()函数,但它没有wotk,如何继续?

1 个答案:

答案 0 :(得分:0)

取自django的内置管理员搜索,这是一个如何实现这一目标的例子。

import operator

def get_search_results(request, queryset, search_term):
    """
    Returns a tuple containing a queryset to implement the search,
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        else:
            return "%s__icontains" % field_name

    use_distinct = False
    search_fields = get_search_fields(request)
    if search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        if not use_distinct:
            for search_spec in orm_lookups:
                if lookup_needs_distinct(queryset.model._meta, search_spec):
                    use_distinct = True
                    break

    return queryset, use_distinct


def get_search_fields(request):
    """
    use double underscores to walk relationsships
    """
    return (
        'nome', 'situacao', 'disciplina__foreign_relation__field',
    )