Erreur Django - la requête correspondante n'existe pas

92

J'ai finalement sorti mon projet au niveau de la production et j'ai soudainement des problèmes que je n'ai jamais eu à gérer en phase de développement.

Lorsque les utilisateurs publient des actions, j'obtiens parfois l'erreur suivante.

Traceback (most recent call last):

  File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)

  File "home/ubuntu/server/opineer/comments/views.py", line 103, in comment_expand
    comment = Comment.objects.get(pk=comment_id)

  File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 131, in get
    return self.get_query_set().get(*args, **kwargs)

  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 366, in get
    % self.model._meta.object_name)

DoesNotExist: Comment matching query does not exist

Ce qui me frustre vraiment, c'est que le projet fonctionne bien dans l'environnement local et en outre, l'objet de requête correspondant existe dans la base de données.

Maintenant, je soupçonne que l'utilisateur accède à la base de données lorsqu'elle est réservée à d'autres utilisateurs, mais il n'y a aucun moyen de prouver mon argument et je n'ai aucune solution.

Quelqu'un a-t-il déjà eu ce genre de problème? Des suggestions sur la façon de résoudre ce problème?

Merci beaucoup pour votre aide à l'avance.

EDIT: J'ai interrogé manuellement la base de données en utilisant les mêmes informations extraites de l'e-mail d'erreur du serveur que j'ai reçu. J'ai pu frapper l'entrée sans aucun problème. En outre, il semble que le même comportement que l'utilisateur a effectué ne soulève pas de problème la plupart du temps, mais plutôt dans certains cas (qui sont encore inconnus). En conclusion, ce n'est certainement pas un problème avec l'entrée manquante dans la base de données.

Chris P
la source
2
Clairement, c'est un problème de données: comment = Comment.objects.get(pk=comment_id)vérifiez que l'identifiant existe dans la base de données
karthikr
3
"python manage.py sqlall" générera le SQL correspondant à vos modèles. Vérifiez s'il correspond au schéma de base de données SQL. Si vous travaillez avec PostgreSQL par exemple, cela peut aussi être un problème de séquence. En conclusion: pouvez-vous apporter plus d'informations sur votre environnement (SQDB, DB, table correspondante dans DB et code dans models.py, ...)?
Ricola3D
@ Ricola3D Bonjour Ricola, j'utilise actuellement MySql DB en l'hébergeant à partir de l'instance Amazon EC2. Et j'utilise le commentaire intégré de Django pour le moment. En attendant, j'essaierai d'exécuter la commande sqlall que vous avez suggérée. Merci.
Chris P

Réponses:

97

votre ligne soulevant l'erreur est ici:

comment = Comment.objects.get(pk=comment_id)

vous essayez d'accéder à un commentaire inexistant.

from django.shortcuts import get_object_or_404

comment = get_object_or_404(Comment, pk=comment_id)

Au lieu d'avoir une erreur sur votre serveur, votre utilisateur recevra un 404 signifiant qu'il essaie d'accéder à une ressource inexistante.

Ok jusqu'à ici, je suppose que vous en êtes conscient.

Certains utilisateurs (et j'en fais partie) laissent les onglets fonctionner pendant longtemps, si les utilisateurs sont autorisés à supprimer des données, cela peut arriver. Une erreur 404 peut être une meilleure erreur pour gérer une erreur de ressource supprimée que d'envoyer un e-mail à l'administrateur.

Les autres utilisateurs accèdent aux adresses de leur historique (même si des données ont été supprimées car cela peut arriver).

christophe31
la source
3
+1 sur les onglets de longue durée. 404 via d'anciens onglets m'arrive beaucoup.
Yuji 'Tomita' Tomita
Merci Chris pour votre suggestion. Ce qui me dérange vraiment, c'est que lorsque j'interroge manuellement la base de données MySql (en utilisant les informations d'erreur que j'ai reçues du serveur), je frappe la bonne entrée sans aucun problème. En outre, la même action lance parfois une exception DoesNotExist mais fonctionne la plupart des autres fois. Cela ne semble pas être le problème avec l'entrée manquante dans la base de données :(
Chris P
J'ai peut-être moins d'utilisateurs, mais avec postgres je n'ai jamais eu ce genre de problèmes. Nous n'avons vraiment pas beaucoup d'informations, votre base de données n'a pas de clustering esclave / maître? Vous n'utilisez pas de cache sur les ensembles de requêtes?
christophe31
@ christophe31 Je n'ai donc pas encore vraiment implémenté d'optimisation des performances de la base de données ni de méthodes de sauvegarde telles que le clustering esclave / maître ou la mise en cache sur des ensembles de requêtes. Je suppose que je vais implémenter ces fonctionnalités et voir si le problème persiste.
Chris P
2
Aussi , vous pouvez ajouter ceci dans la prise: from django.db import connection, connection.connection.close(), connection.connection = Nonepour essayer de réinitialiser db connexion et démarrer à partir d' un nouveau.
christophe31
106

Peut-être que vous n'avez pas d'enregistrement de commentaires avec une telle clé primaire, alors vous devriez utiliser ce code:

try:
    comment = Comment.objects.get(pk=comment_id)
except Comment.DoesNotExist:
    comment = None
Dracontis
la source
3
Meilleure option dans de tels cas. Au lieu de lancer 404 à l'utilisateur, détectez l'erreur et affichez un joli message préconfiguré. Aucun cœur ne brûle.
user12379095 le
Comment cela fonctionnerait-il ici? def previous_job(self): return self.get_previous_by_start_dt(brand=self.brand, status='finished') or NoneJe ne sais pas comment implémenter le try catch ici
snh_nl
23

Vous pouvez utiliser ceci:

comment = Comment.objects.filter(pk=comment_id)
Klang Wutcharin
la source
Eh bien, s'il y a un objet spécifique que vous voulez, vous ne pouvez pas utiliser de filtre car il peut renvoyer une liste vide Si la requête ne correspond pas. Et quand il correspond, vous devez utiliser le premier objet de la liste.
Jay Modi
3
C'est probablement le but: utilisez un filtre et testez si le résultat a zéro ou une entrée, au lieu de générer une exception?
Mike 'Pomax' Kamermans
A noter que Model.objects.filterretournera un Queryset, alors que Model.objects.getretournera un objet. Si l'objet n'existe pas, le premier renverra un jeu de requêtes vide, le second entraînera une Model.DoesNotExisterreur.
ron_g
Comment.objects.filter(pk=comment_id).first()reviendra Nonesi aucun enregistrement n'est trouvé.
steezeburger
13

Vous pouvez essayer de cette façon. utilisez simplement une fonction pour obtenir votre objet

def get_object(self, id):
    try:
        return Comment.objects.get(pk=id)
    except Comment.DoesNotExist:
        return False
Mehedi Hasan
la source