Filtering results in django rest framework
I have the following models
class CustomUser(AbstractBaseUser, PersmissionsMixin):
#custom fields
practice = models.ForeignKey(Practice)
class Customer(models.Model):
#fields
practice = models.ForeignKey(Practice)
class Peri(models.Model):
customer = models.ForeignKey(Customer)
I also want to create an api for the Peri model, but I want to restrict the results to authenticated users who belong to the same practice with the client the peri belongs to. So after creating my serializer for PeriModel, I created a ModelViewSet for it like this
class PeriViewSet(ModelViewSet):
#serializer_class etc
def get_queryset(self):
user = self.request.user
practice = user.practice
return Peri.objects.filter(customer__practice=practice)
The above code will only return those owned by a customer who has the same practice with a logged in user. So something like this:
http://example.com/api/peri/
will return the query selected above. But what about detailed views. Does the verbose ModelViewSet mean a fetch request? Or is it using a pre-existing query calculated get_queryset
?
I mean if my request contains models with id [2,5,6,7] and the user tries to visit the following url
http://example.com/api/peri/9/
it will get any results, assuming peri with id 9 does not have the same practice as the user, does it? Is filtering related to the ListView query related to the DetailView? It would be better If I used this method here in the custom general filtering section
source to share
Take a look at the source code for django-rest-framework ( https://github.com/tomchristie/django-rest-framework ) in the generics.py module:
def get_object (self): "" " Returns the object the view is displaying. You may want to override this if you need to provide non-standard queryset lookups. Eg if objects are referenced using multiple keyword arguments in the url conf. "" " queryset = self.filter_queryset (self.get_queryset ()) [...]
So it get_object
uses get_queryset
to retrieve the object. Thus, filtering is get_queryset
sufficient.
I have to point out that django-rest-framework is a really great framework, but I constantly need to check the ultimate truth (source code) to find answers to questions like yours
source to share