Django:de retour de plusieurs points de vue à partir d'une seule sans la redirection d'URL
-
09-09-2020 - |
Question
Avec la fonction de base de Django, il est simple de basculer entre plusieurs vues différentes en fonction d'une condition, par exemplequelque chose comme:
def base_view(request):
if some_condition():
return foo_view(request)
else:
return bar_view(request)
Je ne peux pas trouver un moyen simple de faire de même avec la nouvelle classe générique point de vue.La seule façon que je peux penser à est de redisrect, que je tiens à éviter pour plusieurs raisons:
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/")
Toutes les suggestions?
La solution
Ceci est équivalent à votre exemple avec des vues basées sur la classe.
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)
Autres conseils
Même si l' Django docs ne dire que la fonction de base générique vues sont désormais obsolète Je pense que la seule raison de changer ce serait si vous avez écrire moins de code.
Si vous êtes toujours fixé sur la commutation, vous devrez d'abord identifier la classe de base de points de vue ou mixin sont les plus appropriées (objet unique, de multiples objets, en fonction de la date, les formulaires, etc.).Si le conditionnel est utilisé pour sélectionner une fonction qui retourne différentes données de contexte ou de modèle pour offrir à la vue, vous pouvez pousser le conditionnel vers le bas dans un substituée get_queryset|get_context_data|get_object|get_template_names
selon votre cas d'utilisation.
Par exemple,
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
Si tout le reste échoue, et vous êtes toujours déterminé à avoir de la classe de base point de vue, vous pourriez probablement aussi remplacer get(self, request, *args, **kwargs)
et faire la commutation de là à la méthode appropriée.L' détaillée docs sont de mieux en mieux mais j'ai encore trouvé moi-même piquer à travers le code source pour trouver comment accomplir ce que je veux.