Django-Fehler - Übereinstimmende Abfrage existiert nicht

92

Ich habe mein Projekt endlich auf Produktionsebene veröffentlicht und plötzlich habe ich einige Probleme, mit denen ich mich in der Entwicklungsphase nie befassen musste.

Wenn die Benutzer einige Aktionen veröffentlichen, wird manchmal der folgende Fehler angezeigt.

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

Was mich wirklich frustriert, ist, dass das Projekt in der lokalen Umgebung einwandfrei funktioniert und außerdem das passende Abfrageobjekt in der Datenbank vorhanden ist.

Jetzt vermute ich, dass der Benutzer auf die Datenbank zugreift, wenn sie anderen Benutzern vorbehalten ist, aber es gibt keine Möglichkeit, mein Argument zu beweisen, und ich habe keine Lösung dafür.

Hat jemand diese Art von Problem schon einmal gehabt? Irgendwelche Vorschläge zur Lösung dieses Problems?

Vielen Dank für Ihre Hilfe im Voraus.

BEARBEITEN: Ich habe die Datenbank manuell mit denselben Informationen abgefragt, die aus der Serverfehler-E-Mail stammen, die ich erhalten habe. Ich konnte den Eintrag ohne Probleme treffen. Darüber hinaus scheint genau das gleiche Verhalten, das der Benutzer ausgeführt hat, die meiste Zeit kein Problem aufzuwerfen, sondern eher in einigen (noch unbekannten) Fällen. Zusammenfassend ist es definitiv kein Problem mit dem fehlenden Eintrag in der Datenbank.

Chris P.
quelle
2
Es handelt sich eindeutig um ein Datenproblem: comment = Comment.objects.get(pk=comment_id)Überprüfen Sie, ob die ID in der Datenbank vorhanden ist
karthikr
3
"python manage.py sqlall" generiert die SQL, die Ihren Modellen entspricht. Überprüfen Sie, ob es dem DB-Schema SQL entspricht. Wenn Sie beispielsweise mit PostgreSQL arbeiten, kann dies auch eine Frage der Reihenfolge sein. Fazit: Können Sie weitere Informationen zu Ihrer Umgebung einbringen (SQDB, DB, entsprechende Tabelle in DB und Code in models.py, ...)?
Ricola3D
@ Ricola3D Hallo Ricola, ich verwende derzeit MySql DB, das es von einer Amazon EC2-Instanz hostet. Und ich benutze vorerst den eingebauten Django-Kommentar. In der Zwischenzeit werde ich versuchen, den von Ihnen vorgeschlagenen Befehl sqlall auszuführen. Vielen Dank.
Chris P

Antworten:

97

Ihre Zeile, die den Fehler auslöst, ist hier:

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

Sie versuchen, auf einen nicht vorhandenen Kommentar zuzugreifen.

from django.shortcuts import get_object_or_404

comment = get_object_or_404(Comment, pk=comment_id)

Anstatt einen Fehler auf Ihrem Server zu haben, erhält Ihr Benutzer eine 404, was bedeutet, dass er versucht, auf eine nicht vorhandene Ressource zuzugreifen.

Ok, bis hierher, ich nehme an, Sie sind sich dessen bewusst.

Einige Benutzer (und ich bin ein Teil von ihnen) lassen Registerkarten lange laufen. Wenn Benutzer zum Löschen von Daten berechtigt sind, kann dies passieren. Ein 404-Fehler ist möglicherweise ein besserer Fehler bei der Behandlung eines gelöschten Ressourcenfehlers als das Senden einer E-Mail an den Administrator.

Andere Benutzer rufen Adressen aus ihrem Verlauf auf (dasselbe gilt, wenn Daten gelöscht wurden, da dies möglicherweise passiert).

christophe31
quelle
3
+1 auf lang laufenden Registerkarten. 404 über alte Tabs passiert mir sehr viel.
Yuji 'Tomita' Tomita
Danke Chris für deinen Vorschlag. Was mich wirklich stört, ist, dass ich beim manuellen Abfragen der MySQL-Datenbank (unter Verwendung der Fehlerinformationen, die ich vom Server erhalten habe) ohne Probleme den richtigen Eintrag gefunden habe. Die gleiche Aktion löst manchmal eine DoesNotExist-Ausnahme aus, funktioniert jedoch meistens. Es scheint nicht das Problem mit dem fehlenden Eintrag in der Datenbank zu sein :(
Chris P
Ich habe vielleicht weniger Benutzer, aber mit Postgres hatte ich nie solche Probleme. Wir haben wirklich nicht viele Informationen, Ihre Datenbank hat kein Slave / Master-Clustering? Sie verwenden keinen Cache für Abfragesätze?
Christophe31
@ christophe31 Ich habe also noch keine DB-Leistungsoptimierung implementiert oder Methoden wie Slave / Master-Clustering oder Caching auf Abfragesätzen gesichert. Ich denke, ich werde diese Funktionen implementieren und sehen, ob das Problem weiterhin besteht.
Chris P
2
Auch Sie können dies in dem Fang hinzufügen: from django.db import connection, connection.connection.close(), connection.connection = Noneum zu versuchen , DB - Verbindung zurückgesetzt und von einem neuen beginnen.
Christophe31
104

Vielleicht haben Sie keinen Kommentardatensatz mit einem solchen Primärschlüssel, dann sollten Sie diesen Code verwenden:

try:
    comment = Comment.objects.get(pk=comment_id)
except Comment.DoesNotExist:
    comment = None
Dracontis
quelle
3
Beste Option in solchen Fällen. Anstatt 404 auf den Benutzer zu werfen, fangen Sie den Fehler ab und zeigen Sie eine nette vorkonfigurierte Nachricht an. Kein Herz brennt.
user12379095
Wie würde es hier funktionieren? def previous_job(self): return self.get_previous_by_start_dt(brand=self.brand, status='finished') or NoneIch weiß nicht, wie ich den try catch hier implementieren soll
snh_nl
22

Sie können dies verwenden:

comment = Comment.objects.filter(pk=comment_id)
Klang Wutcharin
quelle
Wenn es ein bestimmtes Objekt gibt, das Sie möchten, können Sie den Filter nicht verwenden, da er möglicherweise eine leere Liste zurückgibt, wenn die Abfrage nicht übereinstimmt. Und wenn es übereinstimmt, müssen Sie das erste Objekt aus der Liste verwenden.
Jay Modi
3
Vermutlich ist das der Punkt: Verwenden Sie Filter und testen Sie, ob das Ergebnis null oder einen Eintrag enthält, anstatt eine Ausnahme zu generieren?
Mike 'Pomax' Kamermans
Es ist Model.objects.filtererwähnenswert, dass ein Queryset zurückgegeben wird, während Model.objects.getein Objekt zurückgegeben wird. Wenn das Objekt nicht vorhanden ist, gibt das erstere einen leeren Abfragesatz zurück, das letztere führt zu einem Model.DoesNotExistFehler.
Ron_g
Comment.objects.filter(pk=comment_id).first()wird zurückgegeben, Nonewenn keine Datensätze gefunden wurden.
Steezeburger
12

Sie können dies versuchen. Verwenden Sie einfach eine Funktion, um Ihr Objekt zu erhalten

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