JackLeo
JackLeo

Reputation: 4740

python Django - filter + contain readable syntax

i have created little search method. The problem that its hard to read it and ordering seems to be "out of shape". What is the best way to filter query in such manner?

@login_check
def search(request):
    subdomain = request.get_host()                                                                   
    q = request.GET.get('q', None)
    queryset = (
                    SomeObject.objects.filter(title__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created') |
                    SomeObject.objects.filter(description__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created') |
                    SomeObject.objects.filter(comment__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created') |
                    SomeObject.objects.filter(email__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created')
                )
    return object_list(queryset)

In this method object list forms what have to be given back so all i need to do is form a nice query.

Main problem i see here is that filters could be applied after contains since its all the same. How can i achieve this? What is the best/nicest way to filter in such situation?

I've tired to set filters after creating query but then it trows that i cannot apply filters to queries only to model lists. I may be wrong since i'm writing this error from memory, but one thing for sure that it trowed an error.

P.S. I'm using Django 1.1 here and python 2.5.

Upvotes: 0

Views: 1281

Answers (2)

SingleNegationElimination
SingleNegationElimination

Reputation: 156158

you could use a list comprehension to factor out the common tail:

queryset_list = (
    item.filter(alias=Site.objects.get(domain=subdomain)).order_by('created')
    for item in (
        SomeObject.objects.filter(title__icontains=q),
        SomeObject.objects.filter(description__icontains=q),
        SomeObject.objects.filter(comment__icontains=q),
        SomeObject.objects.filter(email__icontains=q)))
queryset = functools.reduce(operator.or_, queryset_list)

Upvotes: 1

Related Questions