使用 Rest API 编写复杂查询的 Django ORM

Posted

技术标签:

【中文标题】使用 Rest API 编写复杂查询的 Django ORM【英文标题】:Django ORM with Rest API writing complex query 【发布时间】:2020-01-03 06:38:00 【问题描述】:

我写了一个功能,比如如果一个人有相关数据,用户就不能执行更新。

给你我的模型:

class Person(models.Model):
    alias = models.UUIDField(primary_key=True,default=uuid.uuid4, editable=False, unique=True)
    name = models.CharField(max_length=20)

class Appointment(models.Model):
    patient = models.ForeignKey(Person, related_name="patient_for_appointment", on_delete=models.CASCADE)
    data = models.CharField(max_length=20)

class Sales(models.Model):
    customer = models.ForeignKey(Person, related_name="customer_for_sales", on_delete=models.CASCADE)
    amount = models.FloatField()

class Prescription(models.Model):
    patient = models.ForeignKey(Person, related_name="Patient_for_prescription", on_delete=models.CASCADE)
    details = models.CharField(max_length=100)

我的主键是UUID,名为alias

这是我的 api 视图:

from django.shortcuts import render
from . models import Person, Appointment, Prescription, Sales
from . serializers import  PersonSerializers
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from rest_framework.response import Response
from rest_framework.exceptions import APIException

class PersonView(RetrieveUpdateDestroyAPIView):
    queryset = Person.objects.all()
    serializer_class = PersonSerializers
    lookup_field = 'alias'

    def update(self, request, *args, **kwargs):
        # person = Person.objects.filter(alias=kwargs['alias'])
        appointment = Appointment.objects.filter(patient__alias=kwargs['alias'])
        prescription = Prescription.objects.filter(patient__alias=kwargs['alias'])
        sales = Sales.objects.filter(customer__alias=kwargs['alias'])

        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        if prescription:
            raise APIException('CANT UPDATE')
        elif appointment:
            raise APIException('CANT UPDATE')
        elif sales:
            raise APIException('CANT UPDATE')
        else:         
            self.perform_update(serializer)

        return Response(serializer.data)

仔细查看上面的一些查询:

        appointment = Appointment.objects.filter(patient__alias=kwargs['alias'])
        prescription = Prescription.objects.filter(patient__alias=kwargs['alias'])
        sales = Sales.objects.filter(customer__alias=kwargs['alias'])

我在这里实现如果一个人有salesappointmentprescription,用户不能执行更新并抛出错误。一切正常

但我的查询存在性能问题,我正在尝试使用人员主键进行单个查询/过滤以获取人员 AppointmentSalesPrescription

以上工作正常,但我正在尝试亲自进行单个查询,如下所示:

person = Person.objects.filter(alias='a person alias/primary key).prefetch_related..............

但我没能做到。谁能帮我实现过滤我的Person 模型以获取其预约、销售和处方?

我在尝试它时已经筋疲力尽,只是卡在这里

【问题讨论】:

【参考方案1】:

您可以通过以下方式制作:

      person=Person.objects.filter(alias=kwargs.get('alias').values("Patient_for_prescription", "patient_for_appointment", "customer_for_sales" , "name", "alias")

将使用此查询列出所有人员数据和相关约会、销售和处方。

查询集可能包含多行,具体取决于 db 中的数据。为避免这种情况,您可以在查询中使用 .first().last()where 条件来为您的视图获取一个人对象,因为您的视图需要一个对象。

【讨论】:

它给我一个错误 django.core.exceptions.FieldError: Cannot resolve keyword 'patient_for_prescription' into field。选项包括:Patient_for_prescription、别名、customer_for_sales、name、patient_for_appointment 只是想确认一下:您在Patient_for_prescription 中有一个大写P,您在查询中使用的是小p吗?因为这可能会导致错误。

以上是关于使用 Rest API 编写复杂查询的 Django ORM的主要内容,如果未能解决你的问题,请参考以下文章

REST API 的 Laravel DB 查询非常慢

Django Rest Api - ManyToManyField,在练习数组中显示'title'而不是'id'

通过 REST API 公开 Redshift 表

使用Swagger编写规范API接口

WCF REST 到 Web API [关闭]

如何在“Zapier 代码”中编写节点获取(Rest-API)?