Помилка Django - відповідний запит не існує


94

Нарешті я випустив свій проект на виробничий рівень, і раптом у мене виникли деякі проблеми, з якими мені ніколи не доводилося стикатися на етапі розробки.

Коли користувачі публікують деякі дії, я іноді отримую таку помилку.

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

Мене насправді розчаровує те, що проект чудово працює в локальному середовищі, а крім того, відповідний об’єкт запиту Є В БД.

Зараз я підозрюю, що користувач отримує доступ до бази даних, коли вона зарезервована для інших користувачів, але немає можливості довести мій аргумент, і я не маю жодного рішення для нього.

Хтось раніше мав подібні проблеми? Будь-які пропозиції щодо вирішення цієї проблеми?

Щиро вдячний Вам за допомогу.

EDIT: Я запитував базу даних вручну, використовуючи ту саму інформацію, отриману з повідомлення електронної пошти про помилку сервера, яке я отримав. Я зміг натиснути запис без жодної проблеми. Крім того, здається, що точно така сама поведінка, яку виконував користувач, більшість випадків не порушує жодної проблеми, а навпаки, у деяких (що поки невідомо) випадках. На закінчення, це точно не проблема з відсутнім записом у базі даних.


2
Очевидно, це проблема даних: comment = Comment.objects.get(pk=comment_id)переконайтесь, що ідентифікатор існує у базі даних
karthikr

3
"python manage.py sqlall" генерує SQL, відповідний вашим моделям. Перевірте, чи відповідає вона схемі БД SQL. Наприклад, якщо ви працюєте з PostgreSQL, це також може бути проблемою послідовності. На закінчення: чи можете ви надати більше інформації про своє середовище (SQDB, DB, відповідна таблиця в БД та код у models.py, ...)?
Ricola3D

@ Ricola3D Привіт, Рікола, я зараз використовую MySql DB, розміщуючи його з екземпляра Amazon EC2. На даний момент я використовую вбудований Django Comment. Тим часом я спробую запустити команду sqlall, яку ви запропонували. Дякую.
Chris P

Відповіді:


98

ваш рядок, що піднімає помилку, тут:

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

ви намагаєтесь отримати доступ до неіснуючого коментаря.

from django.shortcuts import get_object_or_404

comment = get_object_or_404(Comment, pk=comment_id)

Замість того, щоб мати помилку на вашому сервері, ваш користувач отримає 404, що означає, що він намагається отримати доступ до неіснуючого ресурсу.

Гаразд, тут, я гадаю, ви про це знаєте.

Деякі користувачі (і я їх частина) дозволяють вкладкам працювати довгий час, якщо користувачі мають право видаляти дані, це може трапитися. Помилка 404 може бути кращою помилкою для обробки помилки видаленого ресурсу, ніж надсилання електронного листа адміністратору.

Інші користувачі переходять на адреси зі своєї історії (те саме, якщо дані були видалені, оскільки це може статися).


3
+1 на довгих вкладках. 404 через старі вкладки зі мною трапляється багато.
Yuji 'Tomita' Tomita

Дякую Крісу за вашу пропозицію. Що мене насправді турбує, так це те, що коли я вручну надсилаю запит до бази даних MySql (використовуючи інформацію про помилки, отриману від сервера), я ввожу правильний запис без будь-яких проблем. Крім того, та сама дія іноді видає виняток DoesNotExist, але працює більшість інших випадків. Це не схоже на проблему з відсутнім записом у базі даних :(
Chris P

Можливо, у мене менше користувачів, але з postgres у мене ніколи не було подібних проблем. Ми дійсно не маємо багато інформації, у вашій базі даних немає підпорядкованої / ведучої кластеризації? Ви не використовуєте кеш на наборах запитів?
christophe31

@ christophe31 Отже, я ще не реалізував жодної оптимізації продуктивності БД, а також резервних методів, таких як кластеризація підпорядкованих / головних кластерів або кешування наборів запитів. Думаю, я застосую ці функції і подивлюся, чи проблема не зникає.
Chris P

2
Також ви можете додати це в улові: from django.db import connection, connection.connection.close(), connection.connection = Noneщоб спробувати скинути дб з'єднання і почати з нової.
christophe31

106

Можливо, у вас немає записів коментарів з таким первинним ключем, тоді вам слід використовувати цей код:

try:
    comment = Comment.objects.get(pk=comment_id)
except Comment.DoesNotExist:
    comment = None

3
Найкращий варіант у таких випадках. Замість того, щоб кидати користувачеві 404, схопіть помилку та покажіть гарне попередньо налаштоване повідомлення. Серце не горить.
user12379095

Як би це працювало тут? def previous_job(self): return self.get_previous_by_start_dt(brand=self.brand, status='finished') or Noneне знаю, як реалізувати спробу catch тут
snh_nl

24

Ви можете використовувати це:

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

Ну, якщо є конкретний об'єкт, який ви хочете, ви не можете використовувати фільтр, оскільки він може повернути порожній список, якщо запит не відповідає. І коли це збігається, тоді потрібно використовувати перший об’єкт зі списку.
Jay Modi

3
Імовірно, це суть: скористатися фільтром і перевірити, чи має результат результат нуль чи один запис, замість того, щоб генерувати виняток?
Майк 'Помакс' Камерманс

Варто зазначити, що Model.objects.filterповерне набір запитів, тоді як Model.objects.getповерне об'єкт. Якщо об'єкт не існує, перший поверне порожній набір запитів, другий призведе до Model.DoesNotExistпомилки.
ron_g

Comment.objects.filter(pk=comment_id).first()повернеться, Noneякщо записів не знайдено.
steezeburger

13

Ви можете спробувати таким чином. просто використовуйте функцію, щоб отримати свій об'єкт

def get_object(self, id):
    try:
        return Comment.objects.get(pk=id)
    except Comment.DoesNotExist:
        return False
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.