Django - Filtering in DetailView

yprez picture yprez · Feb 22, 2012 · Viewed 8.9k times · Source

I had a function based view that looked like this:

def account_details(request, acc_id):
    account = get_object_or_404(Account, pk=acc_id, person__user=request.user)
    # ...

Which shows you details of your account on success, and 404 if you don't have permissions to access the account or it doesn't exist.

I was trying to implement the same using a class based view (extending DetailView), and came up with this:

class AccountDetailView(DetailView):
    def get_object(self, queryset=None):
        obj = super(AccountDetailView, self).get_object(queryset)
        if obj.person.user != self.request.user:
            raise Http404()
        return obj

The urlconf:

url(r'^account_details/(?P<pk>[0-9a-f]{24})$',
    login_required(AccountDetailView.as_view(model=Account)),
    name='account_details'),

This attitude works, but introduces 2 extra queries, and looks wrong.

Is there a standard or a more elegant way to achieve the same result?

Answer

Chris Pratt picture Chris Pratt · Feb 22, 2012

What arguments would you need to pass to get_queryset anyways? This should do it:

def get_queryset(self):
    qs = super(MyView, self).get_queryset()
    return qs.filter(person__user=self.request.user)