Search code examples
djangotastypie

How can I get the user requesting a POST through Tastypie in a custom view


Inside of a Django 1.5.5 project I am trying to allow mobile clients to bet on encounters through the Tastypie's API. After reading POST datas I can then save the Bet object, but I need the User instance for that matter.

I know bundle.request.user but this reference isn't available in custom views (used with prepend_urls like here.

In my custom view, request.user refers to AnonymousUser. The API resources are protected using Tastypie's ApiKeyAuthentication (do I need to get the current User with the API key located in the header ?).

# ──────────────────────────────────────────────────────────────────────────────
class BaseResource(ModelResource):

    # ──────────────────────────────────────
    def prepend_urls(self):
        try:
            additional_urls = self._meta.additional_urls
        except AttributeError:
            additional_urls = []
        return [url(r'^'+u[0]+'$', self.wrap_view(u[1]), name=u[2]) for u in additional_urls]

    ...

    # ──────────────────────────────────────
    class Meta:
        abstract = True
        allowed_methods = ['get',]
        authentication  = ApiKeyAuthentication()
        authorization   = DjangoAuthorization()
        max_limit = 1000
# ──────────────────────────────────────────────────────────────────────────────
class EncounterResource(BaseResource):

    ...

    # ──────────────────────────────────────
    def bet(self, request, **kwargs):
        self.method_check(request, allowed=['post'])
        encounter = int(kwargs.get('encounter', 0))
        if not encounter:
            return self.create_response(request, {
                'success': False,
                'message': 'Pretty sure you\'re doing something wrong',
            }, HttpApplicationError)
        data = self.deserialize(
            request,
            request.body,
            format=request.META.get('CONTENT_TYPE', 'application/json')
        )
        ...
        return self.create_response(request, {
            'success': True,
        }, HttpCreated)

    # ──────────────────────────────────────
    class Meta(BaseResource.Meta):
        allowed_methods = ['get', 'post',]
        queryset      = Encounter.objects.all()
        resource_name = 'encounters'
        additional_urls = [
            ('encounters/(?P<encounter>\d+)/bet/', 'bet', 'api-encounter-bet'),
        ]

Solution

  • Check out how "dispatch" does it. You want to call the is_authenticated method first, and then you can use request.user

    https://github.com/toastdriven/django-tastypie/blob/master/tastypie/resources.py#L443