1

I am attempting to make buttons on my website that, when clicked, apply a specific filter to my database of models. The model item I would like to sort is a "Clothes_Item" and I would like to apply various sorts of filters. I just want to get this working on a very basic level and then I'll be able to figure it out from there, so let's just say I want to have a singular button that will display all clothing items with gender = "unisex" (where gender is a field of my Clothes_Item model).

index.html

<input class="filter-button" type="button" data="unisex" value="unisex" data_url/>

main.js

$('.filter-button').on('click', function(event) {
    event.preventDefault();
    var element = $(this); //button that was clicked
    $.ajax({
        url : 'filter_clothes/',
        type: 'GET',
        data: { filter_category : element.attr("data") },
});

urls.py

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'filter_clothes/', views.filter_clothes, name='filter_clothes'),
    #more urls...

views.py

def filter_clothes(request):
    filter_category = request.GET.get("filter_category")
    clothes = Clothes_Item.objects.filter(gender=filter_category)
    return HttpResponseRedirect(reverse('index', kwargs={'clothes': clothes}))

def index(request, **kwargs):
    clothes = Clothes_Item.objects.all()
    if 'clothes' in kwargs:
        clothes = kwargs['clohtes']
    if request.user.is_authenticated():
        favorite_clothes_ids = get_favorite_clothes_ids(request)
        return render(request, 'index.html', {'clothes': clothes, 'favorite_clothes_ids': favorite_clothes_ids})
    return render(request, 'index.html', {'clothes': clothes})

I'm recieving a "NoReverseMatch at /filter_clothes/" error and I haven't been able to fix this for awhile. Any help would be greatly appreciated!

EDIT: The above issue has been fixed but I didn't completely resolve the issue. The new error is as follows: Reverse for 'index' with arguments '()' and keyword arguments '{'clothes': ]>}' not found. 1 pattern(s) tried: ['$']

Bryce Morrow
  • 101
  • 1
  • 8

2 Answers2

2

Change url : 'filter_clothes/' to url : '/filter_clothes/'

changer
  • 329
  • 2
  • 4
  • 19
  • It's still giving me an error: Reverse for 'index' with arguments '()' and keyword arguments '{'clothes': ]>}' not found. 1 pattern(s) tried: ['$'] – Bryce Morrow Nov 11 '16 at 21:42
  • It seems that changer has solved your original error. This should solve your new error. http://stackoverflow.com/questions/20993598/reverse-for-index-with-arguments-and-keyword-arguments-not-found-0 – Patrick Falvey Nov 11 '16 at 21:51
  • If I'm not mistaken, that error was due to the fact that the user had not specified a value for name. Have I not already done this in this line? url(r'^$', views.index, name='index'), @PatrickFalvey – Bryce Morrow Nov 11 '16 at 21:59
1

You need to change a regexp pattern for index view in urls.py, as it matches just empty string, but you pass clothes argument to it. For example, if clothes consists of alphanumeric characters, you can change the pattern to r'^/(?P<clothes>\w+)/$'

EDIT: Instead of filter_clothes view, you could pass a get parameters directly to the index view. So it might look like this:

def index(request):
    clothes = Clothes_Item.objects.all()
    filter_category = request.GET.get('filter_category')
    if filter_category:
        clothes = clothes.filter(gender=filter_category)
    if request.user.is_authenticated():
        favorite_clothes_ids = get_favorite_clothes_ids(request)
        return render(request, 'index.html', {'clothes': clothes, 'favorite_clothes_ids': favorite_clothes_ids})
    return render(request, 'index.html', {'clothes': clothes})
Stonecold
  • 348
  • 1
  • 2
  • 10
  • clothes is a queryset of Clothes_Item objects so that particular solution wouldnt work in this case. – Bryce Morrow Nov 12 '16 at 00:19
  • Are you trying to pass a queryset in a url tag, e.g. `{% url 'appname:index' queryset %}? – Stonecold Nov 12 '16 at 00:36
  • No, I'm using ajax to send data to a view function. – Bryce Morrow Nov 12 '16 at 02:04
  • The reason for an error is a `reverse` function in `filter_clothes` view. You can pass only string or integer as an argument to a view, as argument is a part of url. I've added a suggested solution to the answer. – Stonecold Nov 12 '16 at 03:02
  • I mean possible solution. – Stonecold Nov 12 '16 at 03:05
  • Your solution worked for the issue I was having so thanks a lot! It makes much more sense to do it in this way. However, the index view still doesn't seem to be displaying the changes. I've already checked to see that the filter is applied correctly, but the changes don't seem to be reflected in the web page. Any thoughts as to why that may be? I don't know if this would impact it, but I have a never_cache decorator on this view to support other elements of my site. – Bryce Morrow Nov 12 '16 at 19:23
  • I can't say for sure. Check your jquery function that populates the page with a new data. Does it replace old clothes items with filtered ones? – Stonecold Nov 13 '16 at 02:45
  • I thought that my view would be altered by the call to the view function from within the ajax. I never specifically did anything within the ajax to hide or show particular elements. – Bryce Morrow Nov 13 '16 at 20:18
  • No, when you use `render` to send a response to ajax, it recieves raw html - the rendered template. You can use done and fail methods to handle the response, here's an example: [link](https://learn.jquery.com/ajax/jquery-ajax-methods/). So, for example, if you have a `
    ` element, that contains all clothes items, your `.done()` could be: `.done(function (html) { $('.clothes').html(html); })`
    – Stonecold Nov 13 '16 at 21:04
  • Also you can send JSON or XML responses to ajax (django has a [JsonResponse](https://docs.djangoproject.com/el/1.10/ref/request-response/#jsonresponse-objects) object, that takes a python dictionary as first argument and converts it to JSON response). – Stonecold Nov 13 '16 at 21:07