With function based Django view it was simple to switch between several different views based on a condition, e.g. something like:
def base_view(request):
if some_condition():
return 开发者_如何学运维foo_view(request)
else:
return bar_view(request)
I can't find a simple way to do the same with the new class-based generic views. The only way I can think of is to redisrect, which I would like to avoid for various reasons:
def base_view(request):
if some_condition():
return redirect(reverse("name_of_url_to_class-based_view_foo"))
else:
return redirect("/url_to_class-based_view_bar/")
Any suggestions?
This is equivalent to your example with class based views.
class FooView(View):
pass
class BarView(View):
pass
class BaseView(View):
# staticmethod to avoid adding 'self' to the arguments
foo_view = staticmethod(FooView.as_view())
bar_view = staticmethod(BarView.as_view())
def dispatch(self, request, *args, **kwargs):
if some_condition():
return self.foo_view(request, *args, **kwargs)
else:
return self.bar_view(request, *args, **kwargs)
Even though the Django docs do say that the function based generic views are now deprecated I think the only reason to switch would be if you're writing less code.
If you're still set on switching, you'll want to first identify which class based views or mixins are most appropriate (single object, multiple objects, date based, forms, etc.). If the conditional was used to select a function that returns different context data / template to provide to the view, you can push the conditional down into an overridden get_queryset|get_context_data|get_object|get_template_names
depending on your use case.
For example,
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(BaseView, self).get_context_data(**kwargs)
# Add in the publisher
if some_condition():
context['some_data'] = ...
else:
context['other_data'] = ...
return context
If all else fails and you're still determined to have class based views, you could probably also override get(self, request, *args, **kwargs)
and do the switching there to the appropriate method. The detailed docs are getting better but I've still found myself poking through the source code to figure out how to accomplish what I want.
精彩评论