1

我在用着Django 2.0

我有一个模型Note并使用通用更新视图来更新注释对象。

URL配置就像

app_name = 'notes'
urlpatterns = [
    path('<int:pk>/', NoteUpdate.as_view(), name='update'),
]

可以通过它的命名空间设置访问app.urls

/notes/<pk>

我想在加载视图或保存更新值之前在视图中进行一些条件检查。

因为,笔记可以与任何用户共享,并且有一个模板可以查看和更新​​笔记。我想检查用户是否是笔记的所有者,或者笔记是否已与用户共享并已授予写入权限。

class NoteUpdate(UpdateView):
    template_name = 'notes/new_note.html'
    model = Note
    fields = ['title', 'content', 'tags']

    def get_context_data(self, **kwargs):
        context = super(NoteUpdate, self).get_context_data(**kwargs)

        """
        check if note is shared or is owned by user
        """
        note = Note.objects.get(pk=kwargs['pk'])
        if note and note.user is self.request.user:
            shared = False
        else:
            shared_note = Shared.objects.filter(user=self.request.user, note=note).first()

            if shared_note is not None:
                shared = True
            else:
                raise Http404

        context['note_shared'] = shared_note
        context['shared'] = shared

        return context

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super(self.__class__, self).dispatch(request, *args, **kwargs)

这是我尝试过的,get_context_data()但它KeyErrorpk=kwargs['pk']

此外,get_context_data()是检查条件的最佳地点还是get_query()

4

1 回答 1

2

你不需要从 kwargs 获取 pk 因为你的笔记已经作为 self.object 存在所以你的代码将是

class NoteUpdate(UpdateView):
    template_name = 'notes/new_note.html'
    model = Note
    fields = ['title', 'content', 'tags']

    def get_context_data(self, **kwargs):
        context = super(NoteUpdate, self).get_context_data(**kwargs)

        """
        check if note is shared or is owned by user
        """
        note = self.object
        if note and note.user is self.request.user:
            shared = False
        else:
            shared_note = Shared.objects.filter(user=self.request.user, note=note).first()

            if shared_note is not None:
                shared = True
            else:
                raise Http404

        context['note_shared'] = shared_note
        context['shared'] = shared

        return context

    @method_decorator(login_required)
    def dispatch(self, request, *args, **kwargs):
        return super(self.__class__, self).dispatch(request, *args, **kwargs)

根据 this good answer of where to use get_query_setand get_context_data

get_query_set()

由 ListViews 使用 - 它确定要显示的对象列表。默认情况下,它只会为您提供您指定的模型的所有内容。通过覆盖此方法,您可以扩展或完全替换此逻辑。关于该主题的 Django 文档。

class FilteredAuthorView(ListView):
    template_name = 'authors.html'
    model = Author

    def get_queryset(self):
        # original qs
        qs = super().get_queryset() 
        # filter by a variable captured from url, for example
        return qs.filter(name__startswith=self.kwargs.name)

get_context_data()

此方法用于填充字典以用作模板上下文。例如,ListViews 会将 get_queryset() 的结果填充为上例中的 author_list。您可能会最常覆盖此方法以添加要在模板中显示的内容。

def get_context_data(self, **kwargs):
    data = super().get_context_data(**kwargs)
    data['page_title'] = 'Authors'
    return data

然后在您的模板中,您可以引用这些变量。

<h1>{{ page_title }}</h1>

<ul>
{% for author in author_list %}
    <li>{{ author.name }}</li>
{% endfor %}
</ul>
于 2017-12-22T15:15:01.627 回答