【问题标题】:where to check for conditions in generic UpdateView in Django在哪里检查 Django 中通用 UpdateView 中的条件
【发布时间】:2017-12-22 15:00:35
【问题描述】:

我正在使用Django 2.0

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

网址配置是这样的

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() 中尝试过的,但它在 pk=kwargs['pk']

上给出了 KeyError

另外,get_context_data() 是检查条件的最佳位置还是get_query()

【问题讨论】:

    标签: django django-generic-views django-2.0


    【解决方案1】:

    你不需要从 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)
    

    According to this good answer在哪里使用get_query_setget_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>
    

    【讨论】:

      猜你喜欢
      • 2015-07-15
      • 1970-01-01
      • 2015-06-25
      • 2013-07-04
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      相关资源
      最近更新 更多