tags:

views:

32

answers:

2

I've written an index and search view all in one if a GET request is detected it returns just the search results otherwise it returns all records. I've written this view below but I feel like I'm repeating myself a bit too much. Any ideas as to how I can slim this code down a bit would be much appreciated.

def index(request):
    if 'q' in request.GET:
        company_list = Company.objects.filter(
            Q(company__icontains = request.GET['q']) | 
            Q(county__icontains = request.GET['q']) | 
            Q(city__icontains = request.GET['q']) |
            Q(product_description__icontains = request.GET['q'])
        )
        query = request.GET['q']
    else:
        company_list = Company.objects.all()

    paginator = Paginator(company_list, 10)

    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    try:
        companies = paginator.page(page)
    except (EmptyPage, InvalidPage):
        companies = paginator.page(paginator.num_pages)

    if 'q' in request.GET:
        return render_response(request, 'database/index.html', {"companies": companies, "query": query})
    else:
        return render_response(request, 'database/index.html', {"companies": companies})
A: 

Perhaps not the best way but for me this makes it a little bit more readable and minimizes repetition.

def index(request):
    def get_companies(company_list):
        paginator = Paginator(company_list, 10)

        try:
            page = int(request.GET.get('page', '1'))
        except ValueError:
            page = 1

        try:
            companies = paginator.page(page)
        except (EmptyPage, InvalidPage):
            companies = paginator.page(paginator.num_pages)

    return companies

    
    if 'q' in request.GET:
        companies = get_companies(
            Company.objects.filter(
                Q(company__icontains = request.GET['q']) | 
                Q(county__icontains = request.GET['q']) | 
                Q(city__icontains = request.GET['q']) |
                Q(product_description__icontains = request.GET['q'])
            ))
        query = request.GET['q']
        context =  {"companies": companies, "query": query}

    else:
        companies = get_companies(Company.objects.all())
        context = {"companies": companies}

    return render_response(request, 'database/index.html',context)
Trystan Leftwich
A: 

I ended up abstracting the pagination to a separate function, that looks like this.

def pagination(request, objects, pages):
    paginator = Paginator(objects, pages)

    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    try:
        results = paginator.page(page)
    except (EmptyPage, InvalidPage):
        results = paginator.page(paginator.num_pages)

    return results

And I was able to refactor the index/search function down to this.

def index(request):
    if 'q' in request.GET:
        company_list = Company.objects.filter(
            Q(company__icontains = request.GET['q']) | 
            Q(county__icontains = request.GET['q']) | 
            Q(city__icontains = request.GET['q']) |
            Q(product_description__icontains = request.GET['q'])
        )
        query = request.GET['q']
        companies = pagination(request, company_list, 10)
        return render_response(request, 'database/index.html', {"companies": companies, "query": query})
    else:
        company_list = Company.objects.all()
        companies = pagination(request, company_list, 10)
        return render_response(request, 'database/index.html', {"companies": companies})

I still don't like that I am repeating the pagination line but it seems a bit better.

Tristan O'Neil