Reputation: 345
Getting all query set which has a specific value in a list which is ManyToManyField
.
In short, if I type http://localhost:8000/api/pickup/?choosingUser=5
, I would like to get all PickUp_Places
that matches like choosingUser = 5
. choosingUser
comes from ManyToManyField
so a PickUp_Places
model has like choosingUser = [2,3,5,7]
.
I cannot search query sets by a specific value in list
.
When I type http://localhost:8000/api/pickup/?choosingUser=5
, I get all query sets that include ones don't have choosingUser = 5
.
I am using django_filters
in order to filter query sets. I read the documentation but I couldn't find how to get query sets by a value in a list.
If it is alright with you, would you please tell me how to do that?
Thank you very much.
===== ========= ========== =========
My code is like this.
models.py
class PickUp_Places(models.Model):
name = models.CharField(max_length=200, unique=True)
choosing_user = models.ManyToManyField(
settings.AUTH_USER_MODEL, related_name="pick_up")
def __str__(self):
return self.name
class Meta:
db_table = "pickup_places"
serializers.py
class PickUp_PlacesSerializer(serializers.ModelSerializer):
class Meta:
model = PickUp_Places
fields = "__all__"
views.py
class PickUp_PlacesViewSet(viewsets.ModelViewSet):
queryset = PickUp_Places.objects.all()
permission_classes = [
permissions.IsAuthenticatedOrReadOnly
]
serializer_class = PickUp_PlacesSerializer
filter_backends = [filters.DjangoFilterBackend]
filterset_fields = "__all__"
Upvotes: 0
Views: 766
Reputation: 4095
To get choosingUser
from url
override get_queryset
method:
def get_queryset(self):
choosingUser = self.request.query_params.get('choosingUser')
queryset = choosingUser is not None and PickUp_Places.objects.filter(choosing_user__id=choosingUser) or PickUp_Places.objects.all()
return queryset
Elaborated version:
def get_queryset(self):
choosingUser = self.request.query_params.get('choosingUser')
if choosingUser is not None:
queryset = PickUp_Places.objects.filter(choosing_user__id=choosingUser)
else:
queryset = PickUp_Places.objects.all()
return queryset
Upvotes: 1
Reputation: 2120
One way to add filter based on M2M fields is to add filter_fields
to your viewset, something like:
class PickUp_PlacesViewSet(viewsets.ModelViewSet):
queryset = PickUp_Places.objects.all()
permission_classes = [
permissions.IsAuthenticatedOrReadOnly
]
serializer_class = PickUp_PlacesSerializer
filter_backends = [filters.DjangoFilterBackend]
filter_fields = ('choosing_user', )
and then for filtering based on this field use http://localhost:8000/api/pickup/?choosing_user=5
which will return all the places that have user with id = 5
as it's choosing user.
If you want to filter based on multiple choosing_user
s you can do:
class PickUp_PlacesViewSet(viewsets.ModelViewSet):
queryset = PickUp_Places.objects.all()
permission_classes = [
permissions.IsAuthenticatedOrReadOnly
]
serializer_class = PickUp_PlacesSerializer
filter_backends = [filters.DjangoFilterBackend]
filter_fields = {
'choosing_user__id': ['in',]
}
and use http://localhost:8000/api/pickup/?choosing_user=5,1,2
to filter multiple ids.
Upvotes: 0