Jaco
Jaco

Reputation: 1694

Django, pass a javascript variable into ListView to filter a queryset

I'd like to use an Ajax variable within a Django Class based ListView.

Getting the variable into the view is no problem using request.GET.get however, it seems by doing so, I am put into a dilemma.

If I am using def get(self, request) I then have problem using get_queryset and get_context

If I skip using def get(self, request) I have problem getting the Ajax variable into the view.

I'd like to ask for some help to get it working. The ultimate aim is to produce a filtered context that will be used to produce an email.

class ProductListSendView(LoginRequiredMixin, ListView):
    model = Product
    template = 'product/product_email.html'
    
    def get(self, request):
        _req_list =  json.loads(request.GET.get('ids', None))
        _res = [int(i) for i in _req_list]
        return _res
  
    def get_queryset(self, _res):
        queryset = super(ProductListSendView, self).get_queryset()
        qs = queryset.filter(id__in=_res)
        return qs

    def get_context_data(self):
        context = super(ProductListSendView, self).get_context_data()
        context['page_title'] = 'Authors'
        self.send_email(context)
        return context

the js function (for completeness)

var getProducts = function () {
    var table = $('#product_list-table').DataTable();
    var ids = $.map(table.rows('.selected').data(), function (item) {
    return item[1]});


jQuery.ajax({
    type: 'GET',
    url: "/product/list/send/",
    data: { 
        ids: JSON.stringify(ids),
                },
    success: function(data) {},
    error: function(xhr, textStatus, error) {
        console.log(error);  
   } 
});
};

Upvotes: 0

Views: 593

Answers (1)

Eugene Prikazchikov
Eugene Prikazchikov

Reputation: 1904

You can override get_queryset and access request from there using self.request:

    def get_queryset(self):
        _req_list =  json.loads(self.request.GET.get('ids', None))
        _ids = [int(i) for i in _req_list]
        queryset = super(ProductListSendView, self).get_queryset()
        qs = queryset.filter(id__in=_ids)
        return qs

If you need to access _ids not only from get_queryset, but also from get_context_data, then you can store it on self in get method, and then call super to proceed with usual processing:

    def get(self, request):
        _req_list =  json.loads(request.GET.get('ids', None))
        self._ids = [int(i) for i in _req_list]
        return super().get(request)

Of course, if you do that, then in get_queryset and in get_context_data you should acess it through self._ids

Upvotes: 1

Related Questions