Résolue

Django : retour dans la vue précédente

# Optimisation # Django

Gabriel Trouvé

Mentor

Bonjour,

Dans mon projet NetRPG je peux utiliser des consommables à différents endroits :

  • dans la branche avant le combat

  • dans l'arène pendant le combat

J'ai une vue get_item qui est appelée quand je clique sur un consommable. Cette vue fait en sorte de restaurer les points de vie du perso, d'enlver la quantité 1 à l'objet puis redirect vers la branche.

En fait, j'aimerais que si je prends le consommable dans la branche, le redirect se fasse vers la branche et si je prends le conso dans l'arène le redirect se fasse vers l'arène.

Je suis obligé de créer deux vues différentes style : ?

  • get_item_in_branche (où je redirige vers la branche)

  • get_item_in_arena (redirection vers l'arène)

En fait les vues font la meme chose mais redirige vers un endroit différent dans ce cas.

Ou avec Django il existe un autre moyen ?

C'est une question un peu bête, je peux copier coller ma vue et voila, mais il y a peut etre moyen d'être plus efficace.

J'ai pensé créer un champ "statut" au personnage. Dans une arene j'ai un statut combat, et dans la branche un statut dans la branche... Mais ça me parait un peu tiré par les cheveux et pas efficace du tout... dans le sens où copier la vue en changeant le redirect c'est plus rapide. lol

Merci d'avance

Thibault houdon

Mentor

Salut Gab !

Tu as plusieurs façons de faire ça. La première qui me vient en tête serait de récupérer l'URL d'origine avec request.META.get('HTTP_REFERER'). Ça te permet de voir depuis quelle URL ta vue est appelée et de faire la redirection en conséquence.

La deuxième façon serait d'utiliser des paramètres d'URL.

Par exemple si ton URL est netrpg.com/get-item/ tu pourrais dans ta branche l'appeler avec netrpg.com/get-item/?redirect=branch et dans l'arène avec netrpg.com/get-item/?redirect=arena.

Et dans ta vue, tu fais :

def foo(request):
    if redirection := request.GET.get("redirect"):
        if redirection == "arena":
            # redirection vers l'arena
        elif redirection == "branch":
            # redirection vers la branche

Gabriel Trouvé

Mentor

Salut Thibault !

La deuxième façon m'interesse bcq.
C'est celle que tu utiliserais ?

J'ai un peu de mal à voir. En fait dans ton urls.py tu fais un

path("get-item/?redirect=<str:>/")</str:>

Enfin je pense pas que ça soit ça mais dans la doc je n'ai pas vu cette façon d'utiliser le "?"
En fait je pense que j'ai mal compris car j'utilise tout le temps les paramètres d'url mais il y a un truc que je ne comprends pas ici.

:s dsl

Oui la deuxième façon est plus robuste car tu maîtrises vraiment tout, avec le referrer, on ne sait jamais (si tu as une redirection, HTMX ou d'autres choses du genre qui se mettent entre tes deux pages, ça peut modifier la page de provenance et tout casser ^^).

Pour les paramètres d'URL en fait ce sont des paramètres que tu ajoutes dans ton URL mais qui ne sont pas dans ton fichier urls.py.

Tu peux voir sur Docstring par exemple je les utilise pour savoir quel onglet est actif :
https://www.docstring.fr/accompagnement/mentorat/?tab=past

Dans mon cas ici je m'en sers en JavaScript pour voir le nom de l'onglet (qui correspond à un ID dans mon HTML) et l'afficher.

Dans une vue, tu peux accéder à ces paramètres avec request.GET.

C'est la même chose si tu fais un formulaire avec la méthode GET plutôt que POST, tu auras ces données transmises dans l'URL et tu peux les récupérer avec request.GET dans ta vue.

Donc dans ton cas ce serait plutôt dans le HTML que tu indiquerais ces paramètres, par exemple :

<a href="{% url 'get-item' %}?redirect='arena'">Prendre une potion</a>
<a href="{% url 'get-item' %}?redirect='branch'">Prendre une potion</a>

Et dans ta vue :

def foo(request):
    redirection = request.GET.get("redirect")
    if redirection:
        if redirection == "arena":
            return redirect('arena')
        elif redirection == "branch":
            return redirect('branch')

Aaah ok je ne comprenais pas mais oui je suis bête. ça ne va pas je suis avec une méthode POST. Avec POST :

Vue

@require_POST
def get_item_view(request, pk, story_id):
    user = request.user
    story = Story.objects.get(story_id=story_id)
    game_character = CharacterUser.objects.get(user=user, story=story)
    item_in = ItemIn.objects.get(pk=pk)
    item_in.get_item_in(request=request, characteruser=game_character, item_in=item_in)
    item_in.quantity -= 1
    item_in.save()
    if item_in.quantity == 0:
        item_in.delete()
    redirection = request.POST.get("redirect")
    if redirection:
        if redirection == "arena":
            return redirect("rpg:arena", pk=game_character.pk, story_id=story.story_id)

    return redirect("rpg:branch", pk=game_character.pk, story_id=story.story_id)

template

 <form action="{% url 'rpg:get-item' item.pk story.story_id %}?redirect='arena'" method="post">
                            {% csrf_token %}
                            <input alt="image bouton" class="rounded" height="auto" src="{{ item.illustration.illustration.url }}" type="image" width="75"/>
</form>

Ajouter au form :

<input name="redirect" type="hidden" value="arena"/>

Donc comme je suis dans POST je dois ajouter un input avec name redirect et value arena

Merci Thibault !

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.