Reputation: 713
Working with DRF and curious as to whether you can query over a nested item like a list. For example, being able to filter against a query parameter like: http://someurl.com?hashtags=cool
{
"id": 1,
"author": 1,
"hashtags": [
"cool", "gross"
],
"username": "johndoe"
}
I have checked out Django Filters, and was looking for something DRF-specific, kind of like:
hashtags = django_filters.filters.CharFilter(name="hashtags")
but for iterating over a nested List. Obviously CharFilter
wouldn't be correct.
Thanks for any tips or ideas.
-Updated-
The filter obviously does not work but, what was where I was trying to go
views.py
class MentionLatFilter(django_filters.FilterSet):
hashtags = django_filters.filters.SomeFilter(name="hashtags")
class Meta:
model = Mention
fields = ['hashtags']
class MentionList(generics.ListAPIView):
serializer_class = MentionSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_class = MentionLatFilter
def get_queryset(self):
queryset = Mention.objects.all()
placename = self.request.query_params.get('placename', None)
if placename is not None:
queryset = queryset.filter(placename=placename)
username = self.request.query_params.get('username', None)
if username is not None:
queryset = queryset.filter(username=username)
return queryset
models.py
class Mention(models.Model):
author = models.ForeignKey(User)
username = models.CharField(max_length=140, default='Username')
placename = models.CharField(max_length=140, default='SOME STRING')
placemention = models.TextField(max_length=140, default='SOME STRING')
lat = models.DecimalField(max_digits=20, decimal_places=15)
lng = models.DecimalField(max_digits=20, decimal_places=15)
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.placename
class Hashtag(models.Model):
mention = models.ForeignKey(Mention, related_name='hashtags')
tagname = models.CharField(max_length=100)
class Meta:
unique_together = ('mention', 'tagname')
def __unicode__(self):
return '%s' % (self.tagname)
Upvotes: 0
Views: 490
Reputation: 213311
You don't need a custom filter here. Django queryset can follow the reverse relationship very well, for filtering. Check this link: https://docs.djangoproject.com/en/1.8/topics/db/queries/#lookups-that-span-relationships
Here's how you would modify your get_queryset()
method:
class MentionList(generics.ListAPIView):
def get_queryset(self):
hashtag_filter = self.request.query_params.get('hashtags', None)
return Mention.objects.filter(hashtag__tagname=hashtag_filter)
Upvotes: 1