django - 使用 Rest Framework Django API 过滤对象
问题描述
我Person
在 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)
每个人可以有(访问)许多国家并有(说)多种语言。
我想创建一个 API,我将发送到几个languages
和的端点列表countries
,并将返回给我的人,他们的列表中至少有我发送的列表中的一种语言和一个国家。
例如我有
Person(1,['Portugal', 'Spain'],['portugues','spanish'])
,
Person(2, ['Portugal', 'Germany'],['portugues','russian'])
,
Person(3,['France', 'Spain'],['spanish', 'french'])
我发送数据
{
Countries: ['Portugal', 'France'],
Languages: ['russian', 'french']
}
所以在这种情况下它返回Person2
and Person3
。我的带有身份验证的 PersonView
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)
有没有办法做到这一点?我不想通过 url 搜索,而是在正文中发送数据。
解决方案
如果您要使用 requests 测试下面的答案,它会是什么样子。简单性和使用性是我认为您可以跳过不希望 url 包含过滤器信息的要求的原因。
import requests
requests.get(
f'http://{site}',
params={'Countries': ['Portugal', 'France'], 'Languages': ['russian', 'french']}
).json()
requests 库允许将参数作为字典中的列表发送。
需要根据PeopleListView
发送的值更新查询集。
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
这使用The documentation on filtering with Django Rest Framework根据发送的参数更改查询集。
该if.. elif... elif... else
块使用Django 的 orm 中的过滤文档