Skip to content
Advertisement

How do I filter a Django Model by month or year from a JSON dict?

I am trying to parse through a JSON database and filter by month or by year using Django and this is driving me up a wall since this should be simple.

An example of the dict key value pair in the JSON object is formatted as so:

"release_date": "2022-12-25T07:00:00",

From my views.py file, I set up this function to filter the model:

@api_view(['GET'])
def yearList(request,pk):
    queryset = Character.objects.filter(release_date__year=pk)
    serializer = CharacterSerializer(queryset, many=True)
    return Response(serializer.data)

And in my urls.py, I have this urlpattern (ignoring every other pattern)

urlpatterns = [
    path('year/<str:pk>', views.CharacterList.as_view(), name="Character by year" )
]

Character model from models.py as requested:

class Character(models.Model):
    name = models.CharField(max_length=60)
    title = models.CharField(max_length=100)
    game_origin = models.CharField(null=True, blank=True, max_length=100)
    ref_id = models.CharField(null=True, max_length=20)
    ref_link = models.CharField(null=True, max_length=100)
    icon_link = models.CharField(null=True, max_length=100)
    sprite= models.CharField(null=True, max_length=100)
    portrait= models.CharField(null=True, max_length=100)
    attack= models.CharField(null=True, max_length=100)
    special= models.CharField(null=True, max_length=100)
    damaged= models.CharField(null=True, max_length=100)
    voice_1 = models.CharField(null=True, max_length=100)
    voice_2 = models.CharField(null=True, max_length=100)
    line_1 = models.TextField(null=True)
    line_2 = models.TextField(null=True)
    summary = models.TextField(null=True)
    realm = models.CharField(max_length=60)
    release_date = models.DateTimeField(auto_now=False)
    index = models.IntegerField()

    def __str__(self):
        return self.name + " " + self.title

I followed this link to get the idea to append “__year” to the release_date attribute when filtering the queryset. But it’s not filtering the database, I’m still seeing all objects. Where am I going wrong? I can’t look to filter by months if I can’t even get the years filtered, so I’m focusing on the year first. Thank you in advance.

Advertisement

Answer

The typical way to add filters to a view is by accepting query parameters in the URL such as http://localhost:8000/character/?year=1990.

To implement this in your view, you get the parameters from request.GET:

@api_view(['GET'])
def characters(request):
    queryset = Character.objects.filter(release_date__year=request.GET['year'])
    serializer = CharacterSerializer(queryset, many=True)
    return Response(serializer.data)

The complexity of this grows quickly as you add more fields to filter on. The django-filter library provides a great API for configuring filters on all of your models so you don’t have to write all of this yourself.

Advertisement