问题
I am using a generic view to render my blog post item:
class PostUpdateView(UpdateView, LoginRequiredMixin):
model = Post
# etc
I have a model method on the Post
model that results in a boolean True
or False
:
@property
def can_edit(self):
return self.displays_set.count() == 0
If can_edit
is False
for the Post
object, how can I refactor the view to redirect from my UpdateView
to a different DetailView
?
回答1:
Override the dispatch
method, and check obj.can_edit
there. That way the object will be checked for get
and post
requests.
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
def dispatch(self, *args, **kwargs):
obj = self.get_object()
if not obj.can_edit:
return redirect('/readonly-view/')
return super().dispatch(*args, **kwargs)
With this solution, get_object()
is called twice so there is a duplicate SQL query. However this is probably worth it to keep the code simple.
回答2:
I would say that override dispatch
method is best solution,
but if you want to avoid extra database hit, then you need to override get
and post
methods
def get(self, request, *args, **kwargs):
self.object = self.get_object()
if not obj.can_edit:
return redirect('/readonly-view/')
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
self.object = self.get_object()
if not obj.can_edit:
return redirect('/readonly-view/')
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
来源:https://stackoverflow.com/questions/57724022/how-to-redirect-in-a-generic-view