سؤال

I am using django as backend and using AngularJS to pull from my RESTfull endpoints.

And i ran in to a problem which i can't figure the best solution for.

Currently i have this:

/api/planned-meals?from=2014-3-18&to=2014-3-28

Which gives gives me all items between those two dates.

But i want to be able to fetch all items between those two dates from the currently requesting user, but i don't know the id of the user when i call the resource. But in the backend i can set the owner to be the currently requesting user.

Is it bad practice to create another parameter which says the user should be the currently requesting user. It could be like:

/api/planned-meals?from=2014-3-18&to=2014-3-28&user=self

Or is it better practice to create another resource which always returns the items where the requesting user is the owner?

This is my view in Django at the moment:

class PlannedMealList(generics.ListCreateAPIView):
    serializer_class = PlannedMealSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get_queryset(self):
        """
        Overiding the queryset if some parameters isset
        """
        queryset = PlannedMeal.objects.all()
        date_from = self.request.QUERY_PARAMS.get('from', None)
        date_to = self.request.QUERY_PARAMS.get('to', None)
        if date_from is not None and date_to is not None:
            queryset = queryset.filter(date__gte=date_from).filter(date__lte=date_to)
        return queryset

    def pre_save(self, obj):
        obj.user = self.request.user

I hope you can help me or at least give me some ideas of what the best practice is?

هل كانت مفيدة؟

المحلول

I think you can go both ways, but you have to think about a couple of things.

You can do a filter for the "QUERY_PARAMS" and when is "self" you just query for the owner request.user or the name of the user, but of course, there can't be a user named "self" for username or you will have a edge case

If you decide to create your own endPoint for this, you can do it this way, create as many filters as you need like:

from rest_framework import filters

class OwnerFilterBackend(filters.BaseFilterBackend):
    """
    Filter that request user view his own objects
    """
    def filter_queryset(self, request, queryset, view):
        """
        :param request: HTTP Request
        :param queryset: View QuerySet
        :param view: View Instance
        :return: QuerySet filter by the user request as the owner
        """
        return queryset.filter(owner=request.user)

And then just add the filter to your new api view:

class PlannedMealList(generics.ListCreateAPIView):
    serializer_class = PlannedMealSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    filter_backends = (OwnerFilterBackend,)
    ....
    ....

You can apply several filter, like for the date or ordering and it will help to keep it DRY

A example applying many filters

class PlannedMealList(generics.ListCreateAPIView):
        serializer_class = PlannedMealSerializer
        permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
        filter_backends = (OwnerFilterBackend, filters.DjangoFilterBackend, filters.OrderingFilter)
        filter_class = MyFilterClass
        ....
        ....

If you have further questions, I can help you ;)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top