0

I have a django admin tabular inline, in which I have form = ProdForm which holds a modelchoicefield select box as follows;

class ProdForm(forms.ModelForm):
    productid = forms.ModelChoiceField(queryset=Product.objects.filter(active=True),
                                       widget=Select2(select2attrs={"width": "400px"}), )

as you can see, I am using the easy_select2 module, that is enabling providing me with a look up field too.

However, if I try to load this in the corresponding tabularInLine, it never loads because there is a very high number of records (suppose millions). Therefore loading the entire queryset is not possible. I need to find a way to do this so people using the admin can search the object they need, suppose by a name which is one of the attributes on the Product model.

An idea is to keep the search box but not load the queryset initially and hit the db when there are, for example 3 or more letters in the search field, that could maybe work. However, that would include some js that I am not really familiar with and I would prefer some pythonic/django way of doing this.

Or maybe there is a nice django way but I haven't found it and I am at my wits end. I would appreciate any suggestions.

David Louda
  • 498
  • 5
  • 19

1 Answers1

1

Try to use ajax.

You can call ajax when you submit search bar, next search your record in view.py, and at the end display result in console or template.

This is a general example:

file.js

$("#search").submit(function(e){
    e.preventDefault();
    $.ajax({
        type: 'GET',
        url: path_to_view,
        data: {'data':data_from_search_bar},
        success: function(response){
            var result = response['result']
            console.log(result)
        }
        error: 'some_func..'
    })
});

view.py

def get_result(request):
     if request.is_ajax and request.method =="GET":
         response_data = request.GET['data']
         product = ProductModel.objects.get(name=response_data)# or others attrs
         return JsonResponse({'result':product},status=200)

Read here more about ajax:

CFE

pluralsight

geeksforgeeks

mka
  • 153
  • 5
  • Thank you for your answer! This is certainly a useful hint. However, suppose there is the following name: "Asus Zenfone 7, 8GB/128GB" This approach would yield this object only if the name was entered in full. I could bypass this by __icontains but what if I don't want the user to submit/hit enter but to load the possible icontains results as they type? – David Louda Dec 09 '20 at 13:27
  • 1
    In your view try: `products = ProductModel.objects.filter(name__contains=response_data)` and if you want to do it every time when someone write somethink into the input search field insted of `submit` use: `$("#search").bind('input propertychange', function() {` – mka Dec 09 '20 at 13:42
  • also then in your js write `for (var product in response['result']){ content }` because repsonse will be a querydict. I'm not sure how querydict is displayed in js but in your view you can also put this: `pr_array=[] ` `for i in products: pr_dict.append(i.name)` `products = {'result': pr_array}` – mka Dec 09 '20 at 13:49
  • I don't use views for this as this is django admin inline, I am now trying to extend the default template for this so I guess this all will have to be placed there – David Louda Dec 09 '20 at 13:53
  • To edit admin panel check here: [link](https://docs.djangoproject.com/en/3.1/ref/contrib/admin/) – mka Dec 09 '20 at 14:01