Django - Filtering in DetailView

I had a function 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 the details of your account if successful and 404 if you do not have access rights to the account or it does not exist.

I tried to implement the same thing using a class-based view (extension DetailView), and came up with the following:

 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 

Url:

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

This relation works, but introduces 2 additional queries and looks wrong.

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

+4
source share
2 answers

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

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

If you are worried about queries, you can use select_related to pre-fetch user profiles in the query set:

  def get_queryset(self) return Account.objects.select_related("person", "person__user").all() def get_object(self, queryset=None): try: return queryset.get(pk=self.kwargs['acc_id'], person__user=self.request.user) except Account.DoesNotExist: raise Http404 

I have to say that sometimes it’s hard to find things according to class representations

+2
source

Source: https://habr.com/ru/post/1397895/


All Articles