Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest framework filtering by dateTime

I'm trying to filter by dateTime in django restFramework. it seems that it does not work, because it does not filter, it always brings the same results.

Model.py

#Modelo Fechas que formara parte del modelo horario
class Fecha(models.Model):
    fecha_inicio = models.DateTimeField(blank=True, default='')
    fecha_fin = models.DateTimeField(blank=True, default='')

    def __str__(self):
        return self.fecha_inicio, self.fecha_fin

#Modelo Horario
class Horario(models.Model):
    profesional = models.ForeignKey(Profesional, unique=True)
    fechas = models.ManyToManyField(Fecha)

    def __str__(self):
        return self.profesional.user.username 

View.py

class FechaList(generics.ListAPIView):
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    serializer_class = FechaSerializer
    queryset = Fecha.objects.all()
    filter_class = HorarioFilter

Urls.py

 url(r'^horario/$', views.FechaList.as_view())

Filters.py

   class HorarioFilter(django_filters.FilterSet):
    date_start = django_filters.DateTimeFilter(name="fecha_inicio")

    class Meta:
        model = Fecha
        fields = {
            'date_start': ['lte', 'gte', 'lt', 'gt'],
        }

Serializers.py

class FechaSerializer(serializers.ModelSerializer):

    class Meta:
        model = Fecha
        fields = ('fecha_inicio','fecha_fin')

Request: http://127.0.0.1:8000/horario/?date_start__gte=2015-6-28+00:00 . Don't do anything, dont filter but the response it's a listo of "horario" object and give a 200 code.

Thank you!!!! :)

like image 633
Isma9 Avatar asked Nov 10 '17 09:11

Isma9


1 Answers

You can simply use lt, lte, gt, gte to the field you want to filter by, like this: class HorarioFilter(django_filters.FilterSet):

    class Meta:
        model = Horario
        fields = {
            'fecha__inicio': ['lte', 'gte', 'lt', 'gt'],
        }

And your API request would be: GET {{DOMAIN}}/{{RESOURCES}}/?fecha__inicio__gte=2017-6-28+00:00&fecha__inicio__lt=2017-6-29+00:00:00

If you want a cleaner or a custom lookup expr for the query param, you can use create an alias like this:

class HorarioFilter(django_filters.FilterSet):

    class Meta:
        model = Horario
        fields = {
            'started__lte': ['fecha__inicio__lte'], 
            'started__gte': ['fecha__inicio__gte'],
        }

Then your API request will be like: GET {{DOMAIN}}/{{RESOURCES}}/?started__gte=2017-6-28+00:00&started__lte=2017-6-29+00:00:00

And on top of that, assuming you are using the recommended django-filter, and you are on the 1.x. If you didn't specify a global filter backends in your DRF setting, try adding this to your View

filter_backends = (django_filters.rest_framework.DjangoFilterBackend, )
like image 171
PatDuJour Avatar answered Oct 13 '22 20:10

PatDuJour