Search code examples
djangodjango-filter

How to display your queries using filter?


So I am trying to set up a filter for my website and it is not working; It does not give me an error and the url updates like a query is being made but when I click "submit" it still shows all of the content in the page. I can't quite figure out what is wrong.

filters.py

import django_filters
from django_filters import DateFilter
from .models import *

class UserpostFilter(django_filters.FilterSet):
    start_date = DateFilter(field_name = "date_published", lookup_expr='gte')
    end_date = DateFilter(field_name = "date_published", lookup_expr='lte')

    class Meta:
        model = Userpost
        fields = '__all__'
        exclude = ['image', 'user', 'date_published']

models.py

class Userpost(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    Year = models.CharField(max_length = 4)
    Mileage = models.CharField(max_length = 8)
    Make = models.CharField(max_length = 50)
    Model = models.CharField(max_length = 50)
    Price = models.DecimalField(max_digits=15, decimal_places=2)
    email = models.EmailField()
    date_published = models.DateField(default = timezone.now)
    image = models.ImageField(null = True, blank = True, upload_to = r"C:\Users\gabri\Desktop\test\ecommerce\static\images")
    

    def __str__(self):
        return self.Year + " " + self.Make + " " + self.Model
    
    @property
    def imageURL(self):
        try:
            url = self.image.url
        except:
            url = ''
        return url

views.py

def posts(request):
    cars = Userpost.objects.all()

    p = Paginator(Userpost.objects.all(), 9)
    page = request.GET.get('page')
    cars_list = p.get_page(page)
    nums = "a" * cars_list.paginator.num_pages

    myFilter = UserpostFilter(request.GET, queryset = cars)
    cars = myFilter.qs

    context = {'cars':cars, 'cars_list':cars_list, "nums":nums, "myFilter":myFilter}
    return render(request, 'store/userposts.html', context)

userposts.html

<div class = "row">
    <div class="col">
      <div class = "card card-body">

        <form method="get">
           {{myFilter.form}}

          <button class="btn btn-primary" type="submit">Search</button>
        </form>
      </div>
    </div>
</div>
<br>
<div class="row">
    {% for car in cars_list %}
    <div class="col-lg-4">
        <img class="thumbnail" src="{{car.imageURL|default:'/images/transparentLogo.png'}}">
        <div class="box-element product">
            <h6><strong>{{car.Year}} {{car.Make}} {{car.Model}}</strong></h6>
            <hr>
            <a class="btn btn-outline-success" href="{% url 'post_detail' car.pk %}">View</a>
            <h4 style="display: inline-block; float: right"><strong>${{car.Price|floatformat:2}}</strong></h4>

        </div>
    </div>
    {% endfor %}
</div>

I would really appreciate if you guys could help me

EDIT

So I changed the order of the views to first filter and then paginate but it still does the same thing. I get no error, but display all the content from the page rather than the filtered ones.

def posts(request):
    cars = Userpost.objects.all()
    myFilter = UserpostFilter(request.GET, queryset=cars)
    cars = myFilter.qs


    p = Paginator(Userpost.objects.all(), 9)
    page = request.GET.get('page')
    cars_list = p.get_page(page)
    nums = "a" * cars_list.paginator.num_pages

    context = {'cars':cars, "myFilter":myFilter, 'cars_list':cars_list, "nums":nums}
    return render(request, 'store/userposts.html', context)

Solution

  • The paginator should work on the cars not on the orignal queryset, since you are paginate over the filtered results

    def posts(request):
        cars = Userpost.objects.all()
        myFilter = UserpostFilter(request.GET, queryset=cars)
        if not myFilter.is_valid():
             raise ValidationError('filter is invalid')
        cars = myFilter.qs
    
        # This is the change
        p = Paginator(cars, 9)
        page = request.GET.get('page')
        cars_list = p.get_page(page)
        nums = "a" * cars_list.paginator.num_pages
    
        context = {'cars':cars, "myFilter":myFilter, 'cars_list':cars_list, "nums":nums}
        return render(request, 'store/userposts.html', context)