#36607: Improve the documentation by mentioning that "filter(a,b)" may not be the same as "filter(a).filter(b)" on querysets. -------------------------------------+------------------------------------- Reporter: Aaron | Type: | Uncategorized Status: new | Component: Database | layer (models, ORM) Version: 5.2 | Severity: Normal Keywords: | Triage Stage: | Unreviewed Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+------------------------------------- Dear community,
I just got informed about the fact that "filter(a,b)" might not be the same as "filter(a).filter(b)". The following example may be useful for illustrating this. It uses some code that is inspired by our code and won't run without context, but I hope it is illustrating enough. The intend is to filter for MaintenanceOperations. Therefore, we create one: {{{#!python op = MaintenanceOperationFactory() }}} These objects are children of the MaintenanceOperation: {{{#!python maint_a = UnscheduledMaintenanceFactory(operation=op, execution_start="2030-03-10T12:00:00Z") maint_b = UnscheduledMaintenanceFactory(operation=op, execution_start="2030-05-10T12:00:00Z") }}} We construct a first queryset like this: {{{#!python qs1 = MaintenanceOperation.objects.filter(maintenances__execution_start__gt="2030-04-10T12:00:00Z", maintenances__execution_start__lt="2030-04-20T12:00:00Z",) }}} This qs evaluates to: <MaintenanceOperationQuerySet []> (aka the empty list). This happens because neither UnscheduledMaintenance meets both criteria. The underlying sql is this: {{{#!sql SELECT "maintenance_maintenanceoperation"."id" FROM "maintenance_maintenanceoperation" INNER JOIN "maintenance_maintenance" ON ("maintenance_maintenanceoperation"."id" = "maintenance_maintenance"."operation_id") WHERE ("maintenance_maintenanceoperation"."deleted_at" IS NULL AND "maintenance_maintenance"."execution_start" > 2030-04-10 12:00:00+00:00 AND "maintenance_maintenance"."execution_start" < 2030-04-20 12:00:00+00:00) }}} To demonstrate the second case, we build the following queryset: {{{#!python qs2 = MaintenanceOperation.objects.filter( maintenances__execution_start__gt="2030-04-10T12:00:00Z",).filter( maintenances__execution_start__lt="2030-04-20T12:00:00Z",) }}} This qs evaluates to:<MaintenanceOperationQuerySet [<MaintenanceOperation: #1: beauftragt>]>(This list contains the MaintenanceOperation we created at the start) This is different from the first one, because the sql is done with another join: {{{#!sql SELECT "maintenance_maintenanceoperation"."id" FROM "maintenance_maintenanceoperation" INNER JOIN "maintenance_maintenance" ON ("maintenance_maintenanceoperation"."id" = "maintenance_maintenance"."operation_id") INNER JOIN "maintenance_maintenance" T3 ON ("maintenance_maintenanceoperation"."id" = T3."operation_id") WHERE ("maintenance_maintenanceoperation"."deleted_at" IS NULL AND "maintenance_maintenance"."execution_start" > 2030-04-10 12:00:00+00:00 AND T3."execution_start" < 2030-04-20 12:00:00+00:00) }}} I think this should be mentioned in the filter documentation, particularly in the section on joining filters. If this is met with approval I am open to sketching a suggestion. -- Ticket URL: <https://code.djangoproject.com/ticket/36607> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/django-updates/010701993ceae316-ac924e05-c54d-42a7-8946-01397f0200b4-000000%40eu-central-1.amazonses.com.