Django - 在 DetailView 中进行过滤

发布于 2025-01-08 08:52:30 字数 803 浏览 0 评论 0原文

我有一个基于函数的视图,如下所示:

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

urlconf:

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

这种态度有效,但引入了 2 个额外的查询,并且看起来错误。

是否有标准或更优雅的方法来达到相同的结果?

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})

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?

, 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

童话 2025-01-15 08:52:30

无论如何,您需要将哪些参数传递给 get_queryset ?这应该可以做到:

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

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)
孤芳又自赏 2025-01-15 08:52:30

如果您担心查询,可以使用 select_lated 来预取查询集中的用户配置文件:

 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

我不得不说,有时很难让事情适合基于类的视图

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文