Django - фильтрация в DetailView - PullRequest
       21

Django - фильтрация в DetailView

4 голосов
/ 23 февраля 2012

У меня было функциональное представление, которое выглядело так:

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

Показывает данные вашей учетной записи в случае успеха и 404, если у вас нет прав доступа к учетной записи или она не существует.

Я пытался реализовать то же самое, используя представление на основе классов (расширяя DetailView), и придумал следующее:

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'),

Это отношение работает, но вводит 2 дополнительных запроса и выглядит неправильно.

Существует ли стандартный или более элегантный способ достижения того же результата?

Ответы [ 2 ]

15 голосов
/ 23 февраля 2012

Какие аргументы вам нужно будет передать get_queryset в любом случае? Это должно сделать это:

def get_queryset(self):
    qs = super(MyView, self).get_queryset()
    return qs.filter(person__user=self.request.user)
3 голосов
/ 23 февраля 2012

Если вас беспокоят запросы, вы можете использовать select_related для предварительной выборки профилей пользователей в наборе запросов:

 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

Я должен сказать, что иногда трудно привести вещи в соответствие с представлениями на основе классов

...