Apostolos
Apostolos

Reputation: 8101

filtering detail 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 limit the results to authenticated users that belong to the same practice with the customer to whom peri belongs to. So after creating my serializer for PeriModel I created my 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 return only those peri's that belong to a customer that has the same practice with the logged in user. So something like this:

http://example.com/api/peri/

will return the above filtered queryset. But how about detail views. Does the detail view of the ModelViewSet re-evaluate the queryset? Or does it use the preexisting queryset calculated by get_queryset?

What I mean is if my queryset consits of models with id [2,5,6,7] and a user tries to visit the following url

http://example.com/api/peri/9/ 

will he get any results supposing peri with id 9 doesn't have the same practice logged in user has?Does filtering the ListView queryset apply to DetailView also? Would it be better If I used this method here under custom generic filtering section??

Upvotes: 4

Views: 991

Answers (1)

Serafeim
Serafeim

Reputation: 15104

Take a look at the source code of django-rest-framework (https://github.com/tomchristie/django-rest-framework), at 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, get_object uses get_queryset to retrieve the object. So, filtering get_queryset is enough.

I have to notice 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 such as yours

Upvotes: 4

Related Questions