在 Django 的通用 UpdateView 中检查条件的位置
where to check for conditions in generic UpdateView in Django
我正在使用 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()
中尝试的方法,但它在 pk=kwargs['pk']
[=40= 处给出了 KeyError
]
此外,get_context_data()
是检查条件或 get_query()
?
的最佳位置
你不需要从 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)
在哪里使用 get_query_set
和 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>
我正在使用 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()
中尝试的方法,但它在 pk=kwargs['pk']
[=40= 处给出了 KeyError
]
此外,get_context_data()
是检查条件或 get_query()
?
你不需要从 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)
get_query_set
和 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>