Reputation: 1106
I have a model Person
in Django
class Language(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Country(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Person(models.Model):
PersonId= models.UUIDField(
primary_key=True, default=uuid.uuid4, editable=False)
Countries = models.ManyToManyField(Country)
Languages = models.ManyToManyField(Language)
each person can have (visit) many countries and have (speak) many languages.
I want to create an API that I will send to the endpoint list of few languages
and countries
, and will return for me the people, which has at their list at least one of the language and one country from the lists that I sent.
For example I have
Person(1,['Portugal', 'Spain'],['portugues','spanish'])
,
Person(2, ['Portugal', 'Germany'],['portugues','russian'])
,
Person(3,['France', 'Spain'],['spanish', 'french'])
I sent data
{
Countries: ['Portugal', 'France'],
Languages: ['russian', 'french']
}
so in this case it returns Person2
and Person3
.
My PersonView with Authentication
class PeopleListView(ListAPIView):
queryset = Person.objects.all()
serializer_class = PersonSerializer
authentication_classes = [TokenAuthentication, ]
permission_classes = [IsAuthenticated, ]
def get_queryset(self):
return Blog.objects.filter(UserId=self.request.user)
Is there any way to do this? I would not like to search by url but send data in body.
Upvotes: 0
Views: 424
Reputation: 3736
What it would look like if you were to test the answer below using requests. The simplicity and usage is why I think you can skip the requirement of not wanting the url to contain filter information.
import requests
requests.get(
f'http://{site}',
params={'Countries': ['Portugal', 'France'], 'Languages': ['russian', 'french']}
).json()
The requests library allows for parameters to be sent as a list in a dictionary.
The PeopleListView
needs to have the queryset updated based on the values sent.
class PeopleListView(ListAPIView):
serializer_class = PersonSerializer
authentication_classes = [TokenAuthentication, ]
permission_classes = [IsAuthenticated, ]
def get_queryset(self):
"""Returns a list of of People that match the critera"""
# get query parameters
countries = self.request.GET.getlist('Countries', None)
languages = self.request.GET.getlist('languages', None)
# return the filter set based on parameters sent
if countries is not None and languages is not None:
return Person.objects.filter(countries__name__in=countries).filter(languages__name__in=languages)
elif countries is not None and languages is None:
return Person.objects.filter(countries__name__in=countries)
elif countries is None and languages is not None:
return Person.objects.filter(languages__name__in=languages)
else:
return Person.objects.all() # returns everyone if no filters set
This uses the The documentation on filtering with Django Rest Framework to change the query set based on the parameters sent.
The if.. elif... elif... else
block uses The documentation on filtering in Django's orm
Upvotes: 1