【问题标题】:Raw sql query as per URL parameters in django根据 django 中的 URL 参数进行原始 sql 查询
【发布时间】:2015-08-25 18:23:49
【问题描述】:

我的models.py如下:

class Prescription(models.Model):
    date_prescribed = models.DateField()
    doctor = models.ForeignKey(Doctor)  
    pharmacy = models.ForeignKey(Pharmacy)

class Doctor(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()

class Pharmacy(models.Model):
    name = models.CharField(max_length=100)
    status = models.Charfield(max_length=100)

我想要的是一个查询集,它可以找到过去六个月按月分组的处方数。我使用的是 raw_sql,我的 views.py 如下:

from django.db import connection
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(['GET'])
def prescription_trend_overview(request):

    query = '''
    select concat(year(rx.date_prescribed),'-',month(rx.date_prescribed)) as timeline,
    COUNT(rx.id) as total_prescriptions
    from myapp_prescription rx, myapp_doctor doctor, myapp_pharmacy pharmacy
    where pharmacy.id = rx.pharmacy_id and
    doctor.id = rx.doctor_id and
    rx.date_prescribed >= '2014-06-04' and
    rx.date_prescribed <= '2015-08-15'
    group by timeline
    order by year(rx.date_prescribed),
    month(rx.date_prescribed)
    '''

    try:
        cursor = connection.cursor()
        cursor.execute(query)
        descr = cursor.description
        rows = cursor.fetchall()
        result = [dict(zip([column[0] for column in descr], row)) for row in rows]

    finally:
        cursor.close()

    return Response(result, status=status.HTTP_200_OK)

效果非常好,当我访问 url 时得到的输出如下:

目前开始和结束日期是硬编码的,处方计数适用于所有医生和药房。但是,我现在需要根据 3 个参数过滤结果:

  1. 医生
  2. 药房
  3. 开始日期和结束日期

我正在尝试在 URL 中添加这些参数,例如:

myapp/services/overview?doctor=John&pharmacy=Phizer&start_date=2015-7-28&end_date=2015-2-12

如何捕获这些参数并根据 URL 参数动态更改 SQL 查询?

【问题讨论】:

    标签: python django django-rest-framework rawsql


    【解决方案1】:

    Rest 框架提供get_queryset 方法。您可以覆盖它并实现您想要的新功能。

    class PrescriptionTrendOverview(viewsets.ModelViewSet):
        queryset = Prescription.objects.all()
        serializer_class =  PrescriptionSerializer
    
        def get_queryset(self):
            queryset = super(PrescriptionTrendOverview, self).get_queryset()
            doctor_name = self.request.query_params.get('doctor', None)
            pharmacy_name = self.request.query_params.get('pharmacy', None)
            start_date = self.request.query_params.get('start_date', None)
            end_date = self.request.query_params.get('end_date', None)
    
            if doctor_name and pharmacy_name and start_date and end_date:
                # You can write the query set this way:
                queryset = queryset.filter(Q(doctor__name=doctor_name)
                                           & Q(pharmacy__name=pharmacy_name)
                                           & Q(date_prescribed__gte=start_date)
                                           & Q(date_prescribed__lte=end_date))
    
                # or this way
                queryset = queryset.filter(doctor__name = doctor_name,
                                           pharmacy__name = pharmacy_name,
                                           ate_prescribed__gte=start_date,
                                           date_prescribed__lte=end_date)
            return queryset
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-17
      • 2015-11-21
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      相关资源
      最近更新 更多