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?
Working with Filter Easily the most important method when working with Django models and the underlying QuerySets is the filter() method, which allows you to generate a QuerySet of objects that match a particular set of filtered parameters.
Django-property-filter is an extension to django-filter and provides functionality to filter querysets by class properties. It does so by providing sub-classes for Filters and Filtersets to keep existing django-filter functionality. For more details and examples check the documentation.
The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.
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)
If you are worried about the queries, you can use select_related
to prefetch the user profiles in the queryset:
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, it's sometimes difficult to get things to fit with class-based views
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With