使用 django ORM 或原始 sql 查询时出现问题

Posted

技术标签:

【中文标题】使用 django ORM 或原始 sql 查询时出现问题【英文标题】:Issue while working with django ORM or raw sql query 【发布时间】:2021-12-29 07:11:55 【问题描述】:

list_edit_drivers.html - 这是用于在前端显示数据的 html 文件

    $(document).ready(function () 
        $.extend(true, $.fn.dataTable.defaults, 
            columnDefs: [
                
                    targets: '_all',
                    defaultContent: ''
                
            ]
        );
        var table = $('#drivers').DataTable(
            "pageLength": 100,
            "serverSide": true,
            "bSearchable":true,
            "dom": 'blfrtip',
            "ajax": "/fleet/dt/editdrivers/?format=datatables&city_id=city_id",
            "columns": [
                 
                    "data": "employee_id",
                    "mRender": function (data, type, full) 
                        return '<a href="/fleet/driver/list_drivers/city_id/view/' + full.id + '">' + full.employee_id + '</a>';
123                     
                ,
                
                    "data": "uber_name"
                ,
                
                    "data": "mobile"
                ,
                
                    "data": "uber_device_no"
                ,
                
                    "data": "aadhar_no",
                    "bVisible": false,
                ,
                
                    "data": "location.name"
                ,
                
                    "data": "status"
                ,
                
                    "data": "id",
                   
                    "bSortable": false,
                    "mRender": function (data, type, full) 
                        
                        return '<a class="btn btn-sm  btn-primary" href="/fleet/driver/list_drivers/city_id/edit/' + full.id + '">' + 'Edit' + '</a>';
                    
                ]
        );
    );

urls.py - ajax 调用 DriverViewSet url 和 html 渲染 list_edit_drivers url

router.register(r'dt/editdrivers', views.DriverViewSet)
path('driver/list_drivers', views.list_edit_drivers, name='list_edit_drivers')

views.py

@method_decorator(login_required, name='dispatch')
class DriverViewSet(viewsets.ModelViewSet):
    queryset = Driver.objects.filter(is_active=1)
    serializer_class = DriverEditListSerializer

    def get_queryset(self):
        queryset = Driver.objects.filter(is_active=1, city_id=self.request.GET.get('city_id'))
        return queryset

@login_required
def list_edit_drivers(request):
    driver = Driver.objects.filter(city_id=request.session['global_city_id'])
    context = 
        'menu_hiring': 'active',
        'submenu_driver_edit_list': 'active',
        'driver': driver,
        'city_id': request.session['global_city_id']
    
    return render(request, 'hiringprocess/list_edit_drivers.html', context=context)

序列化器.py

class DriverEditListSerializer(serializers.ModelSerializer):
    city = CitySerializer(read_only=True)
    location = LocationSerializer()
    class Meta:
        model = Driver
        fields = ( 'id','employee_id','employer', 'name','uber_name','uber_device_no', 'mobile', 'location', 'city','shift','status', 'aadhar_no')

我需要这个 sql 查询实现更改逻辑。我不需要更改现有的字段名称,只需根据以下 sql 查询更改逻辑。原始查询或 ORM 都可以。

    SELECT fleet_driver.id as driver_id, employee_id, uber_name,fleet_driver.city_id, fleet_driver.mobile,uber_device_no, 
fleet_location.name as location_name,
fleet_driver.status as driver_status, fleet_hiring.status as hiring_status
from fleet_driver 
left join fleet_hiring on fleet_driver.id=fleet_hiring.driver_id
left JOIN fleet_location on
fleet_driver.location_id=fleet_location.id
WHERE (fleet_driver.id<4253 )

sql query output ex.* 模型.py

class Driver(BaseModel):
    employee_id = models.CharField(max_length=8,unique=True,null=True, default=True)  name = models.CharField(max_length=255)
    uber_name = models.CharField(max_length=255, null=True, blank=True)
    mobile = models.CharField(max_length=20,unique=True,null=True, blank=True) uber_device_no = models.CharField(max_length=20,null=True,
    blank=True) 
    city = models.ForeignKey(City,models.CASCADE,verbose_name='City',null=True, blank=True)
    location = models.ForeignKey(Location,models.CASCADE,verbose_name='Location',null=True, blank=True) 
    status = EnumField(choices=['WORKING','ON_LEAVE', 'EXIT', 'REJOINED'], null=True)
 
class Hiring(BaseModel):
    STATUS_CHOICES = (('', 'Type...'),
                       ('HR Interview Pass', 'HR Interview Pass'),
                       ('HR Interview Fail', 'HR Interview Fail'),
                       ('Driving Test Pass', 'Driving Test Pass'),
                       ('Driving Test Fail', 'Driving Test Fail'),
                       ('Test Not Interested', 'Test Not Interested'),
                       ('Test Pending', 'Test Pending'),
                       ('Training Completed', 'Training Completed'),
                       ('Training Pending', 'Training Pending'),
                       ('Onboard', 'Onboard'),
                       ('Allocation Completed', 'Allocation Completed')) 
    status = models.CharField(max_length = 255,choices=STATUS_CHOICES, null=True, blank=True) 
    driver = models.OneToOneField(Driver,models.CASCADE,related_name='driver',verbose_name='Driver',null=True, blank=True)

【问题讨论】:

你也可以粘贴你的模型吗?没有模型很难弄清楚 ORM 的关系。 @raviadhikari 更新 models.py 您面临的“问题”是什么?你根本没有真正解释你的情况。 【参考方案1】:

您提供的 SQL 查询中有一段令人困惑的代码。 id=4253 指的是所有列,只是有一个开销。 我省略了。

orm = Driver.objects.filter(
     # because you have written reverse relation in hiring as driver it looks 
     # confusing. You might want to refactor it to hriring
     driver__status__in=(
          'Allocation Completed',
          'Training Completed'
     ).filter(
          # id__lt=4253,
          # id__gt=4253
)
print(orm.query)

发出以下查询:

SELECT "drivers_driver"."id", "drivers_driver"."employee_id",
"drivers_driver"."name", "drivers_driver"."uber_name", 
"drivers_driver"."mobile", "drivers_driver"."uber_device_no" FROM 
"drivers_driver" INNER JOIN "drivers_hiring" ON 
("drivers_driver"."id" = "drivers_hiring"."driver_id") 
WHERE "drivers_hiring"."status" IN (Allocation Completed, Training Completed)

【讨论】:

以上是关于使用 django ORM 或原始 sql 查询时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

使用原始 SQL 查询生成表,并希望在 Django 中将这些表用作 ORM

[Django] 查看orm自己主动运行的原始查询sql

与原始 sql 相比,Django ORM 性能较差

Django(22)Django执行SQL语句

使用 filter() 和 Q 对象混合的 Django ORM 查询

是否可以将 SQL 注释添加到使用 ORM 构建的查询中?