Django UpdateView中的对象所有权验证

syb*_*tic 2 django django-views django-class-based-views

编辑:

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

原版的:

我正在通过允许用户上传故事以及让作者,发布者等来扩展标准django图书指南,在尝试让故事的作者(创作者)使用updateview的同时,让其他用户重定向离开。

在UpdateStory视图中修改get_object将其设置为关闭,但由于某种原因,回溯通过我的StoryForm 初始化。错误是'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
Run Code Online (Sandbox Code Playgroud)

表格

class StoryForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(StoryForm,self).__init__(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

我还很新,所以可能很明显,但是我已经找了几个小时,却很沮丧。

Ber*_*pac 9

最好的方法是使用另一个 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)
Run Code Online (Sandbox Code Playgroud)

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

  • mixin 可以应用于需要相同功能的所有视图。您当然可以在单个类上重写“dispatch”,但通常有更好的地方(例如“get_queryset”和类似方法)。调度是一种较低级别的方法,当需要更广泛的行为时应该进行修改。 (3认同)

Rag*_*gar 5

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)
Run Code Online (Sandbox Code Playgroud)

PS:我认为不建议您覆盖调度。但是,由于必须同时检查get和post方法,因此覆盖派发会更容易。