7

I need to pass instance id after last / of my @action name method, and I seriously have no idea how...

I have a UserViewSet, which url to access list is : /users/, then i have action called favorite_posts, which is detail=False because I'm filtering by current logged user, and the action refer to user posts, I wanna be able to pass the post_id like /users/favorite_posts/post_id/, because in this case it's more friendly to me than /users/1/favorite_posts/ which I could obtain setting detail=True.

Is there any way to do that?

3
  • Isn't it supposed to be /posts/<id>/? Otherwise you have two paths to the same resource. And I'd suggest to invent something like '/home/' root url for obtaining anything related to current user. /users/ + /users/<id>/ resulting with anything else then list of users and user by id produce ambiguity and misunderstanding of common rest approaches.
    – IVNSTN
    Commented Nov 29, 2018 at 17:23
  • I have manytomany relation inside user to posts, and from this action I wanted to be able to just manipulate that one list, in /posts/ i dont have path to user favorite posts to that only one path to this resource. It seemed to me more logic to manipulate user list on user path, than on post.
    – slqq
    Commented Nov 29, 2018 at 17:35
  • Yes, you've discovered favorite_posts list with post ids, now you want to reach specific post by id. Post is a separate entity which is expected to be discovered at /posts/<id>/.
    – IVNSTN
    Commented Nov 29, 2018 at 18:00

3 Answers 3

14

You can include parameters in your url pattern and have user_id passed to your method like this:

@action(methods=['post'], detail=False, url_path='favorite_posts/(?P<user_id>\d+)', url_name='favorite-posts')
def get_favorite_post(self, request, user_id):
    # Do something
    return Response({...})
4
  • Is there any method to url_path='favorite_posts/(?P<user_id>\d+)' mandatory? I have 'GET', 'POST' and 'DELETE' there, and for get I wanna get list, and pass id only for del and post.
    – slqq
    Commented Nov 29, 2018 at 17:30
  • 1
    @slqq I'm not sure if I followed. You can use any method you like. As for your other question above about having user_id optional, you need to modify the regex in url_pattern to something like this: favorite_posts/(?P<user_id>\d*). This way user_id can be between zero and any number of digits.
    – kaveh
    Commented Nov 29, 2018 at 18:18
  • @slqq still, I recommend separating your methods for list and details, instead of having one action method taking care of different things.
    – kaveh
    Commented Nov 29, 2018 at 18:19
  • When I use 'favorite_posts/(?P<user_id>\d*)' i lose chance to not pass this argument, it's required in this way, even I set user_id=False in method arguments.
    – slqq
    Commented Nov 29, 2018 at 20:06
5

You can use it like this:

@action(methods=['get'], detail=False, url_path='req/(?P<post_id>\d+)')

and get post_id in your method like this: kwargs.get('post_id') or just pass post_id directly to your method.

@action(methods=['get'], detail=False, url_path='req/(?P<post_id>\d+)')
def get_post(request, post_id):
     .....
8
  • Thats working but now I must always pass the 'post_id' and I wanted to return list on get, and pass it only on delete.
    – slqq
    Commented Nov 29, 2018 at 17:37
  • You want to pass it on all viewSet methods? Commented Nov 29, 2018 at 17:47
  • No, no, only on this action, i'm trying to make this <post_id> not a must, so if I don't pass it would be nice to get just a list.
    – slqq
    Commented Nov 29, 2018 at 17:49
  • give a default value to post_id and see how it goes? get_post(request, post_id='') Commented Nov 29, 2018 at 18:01
  • I tried but getting 404 anyway, it look like @action decorator raise it before.
    – slqq
    Commented Nov 29, 2018 at 18:08
0

This only works with r because its regex use url_path=r'favorite_posts/(?P<user_id>\d+)', url_name='favorite-posts'

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.