0

I am working on my first Django project and I need to understand the way reflection is used in django.

  • I have the method category_autocomplete which I use with jQuery to get autocomplete for a category field.
  • I need autocomplete in some more places but on different things. I think it might be a good idea to make into a class for reuse.
  • I have started making the class but I am not sure how to proceed.

The problem is the way django uses the filter function. It has a parameter which goes like <param-name>_icontains. I can easily reproduce the lambda by using getattr and passing parameter name as a string but I cannot figure out how to use reflection to get the parameter name for the filter function.

Any idea how this can be done?

class Autocomplete():
    @staticmethod
    def get_json_autocomplete(self, cur_objects, func):
        results = []
        for cur_object in cur_objects:
            results.append(func(cur_object))
        return json.dumps(results)

    @staticmethod
    def autocomplete(self, request, class_name, attr_name):
        term = request.GET.get('term', '')
        data = Autocomplete.get_json_autocomplete(
            #Problem here
            class_name.objects.filter(attr_name=term),
            lambda x: getattr(x, attr_name)
        )
        return HttpResponse(data, 'application/json')

def _get_json_autocomplete(cur_objects, func):
    results = []
    for cur_object in cur_objects:
        results.append(func(cur_object))
    return json.dumps(results)

def category_autocomplete(request):
    term = request.GET.get('term', '')
    data = _get_json_autocomplete(
        Category.objects.filter(name__icontains=term),
        lambda x: x.name
    )
    return HttpResponse(data, 'application/json')

1 Answer 1

1

What I believe you're looking for is **, take a look here and here.

So that part of your code could be:

def autocomplete(self, request, class_name, attr_name):
    term = request.GET.get('term', '')
    data = Autocomplete.get_json_autocomplete(
        class_name.objects.filter(**{attr_name + '__icontains': term}),
        lambda x: getattr(x, attr_name)
    )
    return HttpResponse(data, 'application/json')
Sign up to request clarification or add additional context in comments.

2 Comments

I think you want a double underscore: attr_name + '__icontains': there.
Missed that, Thanks ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.