Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-viewsdjango-filter

How to filter query objects by date range in DRF?


I have simple model:

models.py

class Report(models.Model):

    title = models.CharField(max_length=250)
    created_date = models.DateField()

Created filters.py file and using django-filters package wrote FilterSet:

from .models import Report

class ReportFilter(django_filters.FilterSet):
    created_date = django_filters.DateFromToRangeFilter()
    class Meta:
        model = Report
        fields = ['created_date']

Simple views.py:

from .filters import ReportFilter
from .models import Report

def Reports(request):
    reports = Report.objects.all()
    myFilter = ReportFilter(request.GET, queryset=reports)
    reports = myFilter.qs
    return render(request, 'dashboard/index.html', {'reports': reports, 'myFilter': myFilter})

And the last file index.html:

{% block content %}

<form method="get" style="display: block; width: 335px; margin: 20px auto;">
    {{myFilter.form}}
    <button type="submit">Search</button>
</form>

{% if reports %}
    {% for report in reports %}
        <tr>
            <td>
                {{ report.title }}
            </td>
            <td>
                {{ report.created_date }}
            </td>
        </tr>
    {% endfor %}
 {% endif %}
</table>

{% endblock content %}

Question in short: How to do it DRF? (beginner in DRF)

What I tried so far:

serializers.py

from rest_framework import serializers
from .models import Report

class ReportSerializer(serializers.ModelSerializer):
    class Meta:
        model = Report
        fields = '__all__'

views.py

from .filters import ReportFilter
from .serializers import ReportSerializer
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from .models import Report

class ReportViewSet(viewsets.ModelViewSet):
    queryset = Report.objects.all()
    serializer_class = ReportSerializer
    filter_backends = [DjangoFilterBackend,]
    filterset_class = ReportFilter

Did not change filters.py and added all additions to settings.py file (when installed django-filter and etc.), but NO LUCK ;(

Help, please...

============================================

UPDATED:

views.py

from django.urls import path, include
from rest_framework import routers
fom .views import ReportViewSet

r = routers.DefaultRouter()
r.register(r'^report/$', ReportViewSet)

urlpatterns = [
   path('', include(r.urls))
]

Solution

  • In a simple way you can override .filter_queryset method and use the range lookup to filter dates.

    views.py

    class ReportViewSet(viewsets.ModelViewSet):
        queryset = Report.objects.all()
        serializer_class = ReportSerializer
    
        def filter_queryset(self, queryset):
            date_after = self.request.GET.get('date_after', None)
            date_before = self.request.GET.get('date_before', None)
            if date_after and date_before:
                queryset = queryset.filter(created_date__range=[date_after, date_before])
            return super().filter_queryset(queryset)
    

    endpoint

    http://localhost:8000/reports/?date_after=yyyy-mm-dd&date_before=yyyy-mm-dd
    

    Or, use one of the listed Third party packages. Personally I have tried django-rest-framework-filters, but the project is not updated since 2020 and that will cause problems with the latest versions of Django due to the removal of some packages.