Django exists query не работает в if и else clause?

В приведенном ниже примере, если таблица Medicine состоит из medicine_name, то запрос выполняется нормально, но если название лекарства не существует в соответствующей таблице, то возникает ошибка.

Соответствующий запрос не существует

views.py Код

@api_view(['POST'])
    def addPeople(request):
    m = People()
    m.bp_no = request.POST['bp_no']
    m.name = request.POST['name']
    m.corporation_name = request.POST['corporation_name']
    m.medicine_name = request.POST['medicine_name']
    m.no_of_medicine = request.POST['no_of_medicine']

    existing = Medicine.objects.get(medicine_name=m.medicine_name).no_of_medicine -  int(m.no_of_medicine)
    p_key = Medicine.objects.get(medicine_name=m.medicine_name).id
    if Medicine.objects.filter(medicine_name=m.medicine_name).exists():
      if existing > 0:
      m.save()       
      Medicine.objects.filter(id=p_key).update(no_of_medicine=existing)
      return Response({"message": "Successfully Recorded"})
      else:
       return Response({"message": "Not much Medicine Stored"})
    else:
       return Response({"message": "Medicine is not Stored"})

models.py

class People(models.Model):
    bp_no = models.IntegerField(blank=False,null=False)
    name = models.CharField(blank=False,null=False,max_length=200)
    corporation_name = models.CharField(blank=False,null=False,max_length=200)
    medicine_name = models.CharField(blank=False,null=False,max_length=200)
    no_of_medicine = models.IntegerField()

class Medicine(models.Model):
    medicine_name = models.CharField(null=False,blank=False,max_length=200)
    no_of_medicine = models.IntegerField(null=False,blank=False)

    def __str__(self):
        return self.medicine_name

Ошибка Traceback: Если таблица Medicine не содержит соответствующего имени фильтра, то будет показана эта ошибка

    Internal Server Error: /api/add-people/
Traceback (most recent call last):
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\views\generic\base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\rest_framework\decorators.py", line 50, in handler
    return func(*args, **kwargs)
  File "E:\django\backend\medirecords\api\views.py", line 37, in addPeople
    existing = Medicine.objects.get(medicine_name=m.medicine_name).no_of_medicine -  int(m.no_of_medicine)       
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\MonirHossain\AppData\Roaming\Python\Python39\site-packages\django\db\models\query.py", line 435, in get
    raise self.model.DoesNotExist(
api.models.Medicine.DoesNotExist: Medicine matching query does not exist.

Я не тестировал это, но чисто с точки зрения обработки не найденных объектов, у меня есть предложение, которое вы можете попробовать, чтобы упростить условия / поток.

.get(): Заверните в try / except

get(*args, **kwargs) вызывает Model.DoesNotExist, если не найден.

Когда возникает ошибка not found, вам нужно определить, как вы хотите ее обработать. Например, вы можете иметь значение возврата по умолчанию или выдать ошибку.

В этом случае код потерпит неудачу, если существующее лекарство не будет найдено, поэтому я попрошу его поднять.

@api_view(["POST"])
def addPeople(request):
    medicine_name = request.POST["medicine_name"]
    try:
        medicine = Medicine.objects.get(medicine_name=medicine_name)
    except Medicine.DoesNotExist:
        return Response({"message": "Not much Medicine Stored"})
    m = People()
    m.bp_no = request.POST["bp_no"]
    m.name = request.POST["name"]
    m.corporation_name = request.POST["corporation_name"]
    m.medicine_name = medicine_name
    m.no_of_medicine = request.POST["no_of_medicine"]

    existing = medicine.no_of_medicine - int(m.no_of_medicine)

    p_key = medicine.id
    if medicine.exists():
        if existing > 0:
            m.save()
            medicine.num_of_medicine = existing
            medicine.save(update_fields=["num_of_medicine"])
            return Response({"message": "Successfully Recorded"})
        else:
            return Response({"message": "Not much Medicine Stored"})
    else:
        return Response({"message": "Medicine is not Stored"})
  • Проверка объекта перемещения раньше

    Поскольку запрос полагается на Medicine, это должно быть поймано как можно раньше.

  • Использует try/catch, так как .get() всегда будет вызывать ошибку, когда объект не найден

    .

    Альтернативой является .exists() или filter(*args, **kwargs) + .first()

  • Обновление зависимой модели через Model.save() и ограничение поля, обновленного до num_of_medicine через update_fields.

get_object_or_404()

get_object_or_404(klass, *args, **kwargs) также можно использовать вместо предыдущего блока try/catch:

from django.shortcuts import get_object_or_404

medicine = get_object_or_404(Medicine.objects.all(), medicine_name=m.medicine_name)
existing = medicine.no_of_medicine - int(m.no_of_medicine)

Заключительное примечание

Я предполагаю, что это пример, но также может быть полезно проверить request.POST["no_of_medicine"] в данных POST на основе внутреннего источника истины, чтобы убедиться, что это не подделка.

Вернуться на верх