【问题标题】:Object ownership validation in Django UpdateViewDjango UpdateView 中的对象所有权验证
【发布时间】:2023-03-16 22:52:01
【问题描述】:

编辑:

对我来说更好的解决方案是使用权限系统,特别是因为我需要其他类型的受控对象访问。我现在使用 Django-guardian 来帮助处理这样的对象级权限。

原文:

我通过让用户上传故事以及让作者、出版商等对标准 django 图书指南进行了一些扩展。我试图只让故事的作者(创作者)使用更新视图,其他用户被重定向离开。

在 UpdateStory 视图中修改 get_object 将其关闭,但由于某种原因回溯通过我的 StoryForm init。错误是'HttpResponseRedirect' object has no attribute '_meta'

views.py

class UpdateStory(LoginRequiredMixin, UpdateView):
    model = Story
    template_name = 'stories/story_update.html'
    form_class = StoryForm

    def get_object(self, queryset=None):
        obj = super(UpdateStory, self).get_object()
        if not obj.author == self.request.user:
            return redirect(obj)
        return obj

forms.py

class StoryForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(StoryForm,self).__init__(*args, **kwargs)

我还是新手,所以这可能很明显,但我一直在寻找几个小时,我被难住了。

【问题讨论】:

  • 我不明白你想要什么。您介意解释一下您的问题到底是什么吗,对我来说,您似乎在使用基于类的视图时遇到了错误,这似乎是因为您没有在里面放入元属性。
  • 查看 ragsagar 的回答,了解错误出现的原因。我没有定义 UpdateView 元的任何方面,也不需要。我只是想添加一种方法来验证只有创建对象的用户(其“作者”)才能编辑该对象。

标签: django django-views django-class-based-views


【解决方案1】:

http://ccbv.co.uk/projects/Django/1.5/django.views.generic.edit/UpdateView/

通过以上链接了解UpdateView 的工作原理。 get_object 应该返回模型实例,它不应该返回 HttpResponseRedirect 对象,这就是您收到该错误的原因。

尝试在dispatch 方法中进行检查,如下所示。

def dispatch(self, request, *args, **kwargs):
    """ Making sure that only authors can update stories """
    obj = self.get_object()
    if obj.author != self.request.user:
        return redirect(obj)
    return super(UpdateStory, self).dispatch(request, *args, **kwargs)

PS:我想不建议覆盖调度。但作为你 必须检查 get 和 post 方法,覆盖调度 会更容易。

【讨论】:

  • Dispatch 似乎是添加功能的好方法。你能详细说明为什么不推荐它吗? Google-ing 为它提供了很多覆盖,我找不到任何具体的建议来说明为什么不这样做。
  • 将其标记为正确,因为它还解释了错误并提供代码(谢谢!),但我认为 Berislav Lopac 认为这是最有效的 mixin,因为有几个视图会使用它.
  • 我相信重写调度和调用 self.get_object() 将导致 self.get_object() 的冗余调用。分别覆盖 get 和 post 可以避免这种多余的调用。
【解决方案2】:

最好的方法是使用另一个 mixin,如下所示:

class AuthorRequiredMixin(object):
    def dispatch(self, request, *args, **kwargs):
        if self.object.author != self.request.user:
            return HttpResponseForbidden()
        return super(AuthorRequiredMixin, self).dispatch(request, *args, **kwargs)

当然您可以返回另一个HttpResponse,但请记住这里的正确用法。

【讨论】:

  • 如何从AuthorRequiredMixin 中访问self.object
  • 你没有——mixins 的重点是它们不是直接实例化的。相反,您需要通过继承基视图类和 mixin 来创建自定义视图。
  • 好的,谢谢!但在那种情况下,我不明白为什么不建议直接在视图中覆盖dispatch
  • 可以将 mixin 应用于所有需要相同功能的视图。您当然可以在单个类上覆盖 dispatch,但通常有更好的地方(例如 get_queryset 和类似方法)。 Dispatch 是一种较低级别的方法,应在需要更广泛的行为时进行修改。
  • 呃,你说得对,@knbk,我不假思索地遵循了标准模式。将更新答案。
猜你喜欢
  • 1970-01-01
  • 2017-05-13
  • 2017-02-19
  • 2017-10-30
  • 2020-09-14
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多