Niladry Kar
Niladry Kar

Reputation: 1203

TypeError get_queryset() missing 1 required positional argument: 'pk'

I am working on a accounting application...

I have a model called group which I want to make inside a specific company...

I mean different company will have different set of groups

So,I have tried some thing like this in my list view

class group1ListView(LoginRequiredMixin,ListView):
    model = group1

    def get_queryset(self, pk):
        company_details = get_object_or_404(company, pk=pk)
        return self.model.objects.all().filter(Q(User=self.request.user) & Q(Company=company_details.id))

The User and Company fields are related through foreign key in my group1 model..

But getting this error:

TypeError get_queryset() missing 1 required positional argument: 'pk'

Can any one tell me what I am doing wrong in this??

Thank you

Upvotes: 3

Views: 3336

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476719

The pk is not a parameter in the get_queryset, only the self is.

The positional and named parameters of the URL, are stored in self.args and self.kwargs respectively.

So you can fix the get_queryset to:

class group1ListView(LoginRequiredMixin,ListView):
    model = group1

    def get_queryset(self):  # no pk parameter
        company_details = get_object_or_404(company, pk=self.kwargs['pk'])
        return self.model.objects.filter(
            User=self.request.user,
            Company=company_details.id
        )

You can however boost efficiency by writing a single query (but the semantics is slightly different), like:

class group1ListView(LoginRequiredMixin,ListView):
    model = group1
    allow_empty = False

    def get_queryset(self):  # no pk parameter
        return self.model.objects.filter(
            User=self.request.user,
            Company=self.kwargs['pk']
        )

We can add an allow_empty = False in case we want to raise a 404 when no such group1s can be found.

Your urls.py of course needs to pass the pk value, for example:

# app/urls.py

urlpatterns = [
    url(r'^(?P<pk>\d+)$',views.group1ListView.as_view(),name='grouplist')
]

So you then can query the groups of a company with a path that has the id of the company. If this is the root URL, it is thus something like host.org/123

I think it is however advisable to rename the parameter to company_pk, since right now, you "hint" that this is the pk of the group1 model, not of the Company. This confusion can result in queries that look correct, but are not. Most developers will find it strange if they see a query like

group1.objects.get(pk=self.kwargs['company_pk'])

but not when they see

group1.objects.get(pk=self.kwargs['pk'])

Upvotes: 5

Related Questions