Résolue

If instance est True après un instance.delete()

# Résolution d'erreurs # Bases de données # Django

Gabriel Trouvé

Mentor

Bonsoir,

Dans la vue ci-dessous, si la vie de l'ennemi est inférieur ou égale à 0, enemy.delete() est exécuté. ça fonctionne il n'est plus dans ma BDD.

Sauf que, même si le enemy.delete() est exécuté, le if enemy est True et enemy.action_attack est exécuté.

Alors qu'est-ce qui pourrait faire que if enemy soit True alors que le enemy.delete() a fonctionné ?

Si on met un print(enemy) après le if enemy j'ai bien l'instance qui s'affiche.

J'ai cru lire qu'il pouvait se passer quelque chose avec la mémoire ? (ça me parait bizarre).

Merci d'avance ^^

def enemy_attack_view(request, pk, story_id):
    user = request.user
    story = Story.objects.get(story_id=story_id)
    enemy = EnemyUser.objects.get(pk=pk)
    game_character = CharacterUser.objects.get(user=user, story=story)

    if request.method == "POST":
        game_character.action_attack(enemy=enemy)
        if enemy.life <= 0:
            enemy.delete() # c'est bien delete ici

        if enemy: # mais c'est quand même True
            enemy.action_attack(game_character=game_character)
            if game_character.life <= 0:
                game_character.delete()
                enemy.delete()
                return redirect("rpg:game-over")

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

Hello,

tu veux dire qu'il serait gardé en mémoire tempon ? J'avais déjà eu ce genre de problème sur une app streamlit. Est ce que au lieu de faire if enemy tu peux essayer de faire if enemy is not None ?

Il me semble qu'il y a une petite subtilité entre le test False et None

Je pense qu'il faut refaire enemy = EnemyUser.objects.get(pk=pk) apres la partie ou tu delete, l'instance reste meme si il est supprimé de la BDD

Gabriel Trouvé

Mentor

Bonjour tout le monde ! ^^

PA : enemy is not None j'ai le même problème.

Christian : DoesNotExist.

Je me demande s'il n'y a pas un problème de mémoire dans ce cas.

Mais je l'avais contourné avec if enemy.life > 0.

Donc, quand tu fais une requete après le delete DoesNotExist. Par contre, si tu ne fais pas de requête tu peux toujours accéder aux attributs de l'ennemi qui est normalement delete()...

Curieux !

Dans mon cas je ne suis pas bloqué j'ai contourné en utilisant une condition avec l'attribut.

Merci à vous 2 !

Salut Gab !

En fait là il y a quelque chose de bien important à saisir : la différence entre une variable avec ses attributs dans la mémoire de Python, et tes données dans la base de données.

Quand tu utilises enemy.delete(), l'objet est supprimé de la base de données.

MAIS, la référence à l'objet dans la mémoire reste intacte.

Donc la structure conditionnelle if enemy vérifie si la variable enemy existe toujours en mémoire et non si elle existe dans la base de données.

C'est pour ça que ton if enemy est toujours évaluée à True.

Tu as donc bien contourné le problème parce que tu vérifies si enemy.life est supérieur à 0, ce qui est très différent car là, tu interroges un attribut directement. Et à ce moment dans ton script, l'instance enemy (ta variable), existe toujours, avec ses attributs. Le fait de supprimer les données dans la base de données ne supprime pas ta variable et ses attributs.

Si tu souhaites supprimer la variable de la mémoire, tu peux utiliser del enemy, et là tu vas supprimer la variable et après si tu fais if enemy tu auras un NameError parce que la variable n'existera plus.

Gabriel Trouvé

Mentor

merci Thibault ! je n'y aurais jamais pensé !

super intéressant !

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.