Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using same lookup kwarg for base and nested views #270

Open
Kangaroux opened this issue Aug 2, 2022 · 2 comments
Open

Using same lookup kwarg for base and nested views #270

Kangaroux opened this issue Aug 2, 2022 · 2 comments

Comments

@Kangaroux
Copy link

Suppose I have a resource company with a nested resource users:

/company/<pk>
/company/<company_pk>/users

I rely on the company_pk kwarg to check if request.user has permissions, but because the naming is different, I need to create two permission classes: one for nested views and one for the base resource.

I tried setting lookup_url_kwarg = "company_pk" on the CompanyViewSet but that generates the nested routes with company_company_pk. Setting lookup="" on the router generates _company_pk.

It's not a big deal to create a couple extra permission classes, or to make a custom router that generates the nested lookups like I want, but I wanted to know if this is possible with the library as-is

@alanjds
Copy link
Owner

alanjds commented Aug 2, 2022

Hi, @Kangaroux. Thanks for reaching out.

I see what you mean, but I did not knew that it leads to the need to create two permission classes :/
And by heart I did not remember if there is a way to enforce the url var you want. Sorry for it.

I will take a look on the DRF docs and if I find something I ping you. For today, no I have not a better idea 🤷.

@alanjds
Copy link
Owner

alanjds commented Aug 3, 2022

Hey @Kangaroux, I got some more understanding over the lookup value.

First, the lookup name cames from this pieces of code:

If you really want to get rid of the company_ thing on the nested resource, you can play with the .nest_prefix attribute of the nested router. Yet I do not guarantee that there will be no side-effects, nor that the stuff will not break.

Conceptually, the parent lookup is about how to get the parent object from the child object!

I mean:

# models.py
class Company(models.Model):
    ...

class User(models.Model):
    company = models.ForeignKey('Company', ...)

That would make sense to produce:

/company/<pk>/
/company/<company_pk>/users/<pk>/

As it ease the task to reach the Company from the User inside the View:

User.objects.get(company_pk=self.kwargs['company_pk'], pk=self.kwargs['pk'])
# or more generically:
User.objects.get(**self.kwargs)

Also, in the View for /company/<company_pk>/users/<pk>/ the .get_object() is implemented by default by DRF like:

        filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
        obj = get_object_or_404(queryset, **filter_kwargs)

then the <company_pk> is just unused.

Hope this to helps to understand how and why things are as they are today, yet any change proposal will be very welcome from my side 👍

Thanks again,
Best regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants