@@ -317,10 +317,18 @@ We will use the following example model::
317
317
def __str__(self):
318
318
return self.name
319
319
320
- .. fieldlookup :: embeddedmodelarrayfield.overlap
320
+ KeyTransform
321
+ ^^^^^^^^^^^^
321
322
322
- ``overlap ``
323
- ^^^^^^^^^^^
323
+ Key transforms for :class: `EmbeddedModelArrayField ` allow querying fields of
324
+ the embedded model. This is done by composing the two involved paths: the path
325
+ to the ``EmbeddedModelArrayField `` and the path within the nested embedded model.
326
+ This composition enables generating the appropriate query for the lookups.
327
+
328
+ .. fieldlookup :: embeddedmodelarrayfield.in
329
+
330
+ ``in ``
331
+ ^^^^^^
324
332
325
333
Returns objects where any of the embedded documents in the field match any of
326
334
the values passed. For example:
@@ -335,10 +343,10 @@ the values passed. For example:
335
343
... name="Third post", tags=[Tag(label="tutorial"), Tag(label="django")]
336
344
... )
337
345
338
- >>> Post.objects.filter(tags__label__overlap =["thoughts"])
346
+ >>> Post.objects.filter(tags__label__in =["thoughts"])
339
347
<QuerySet [<Post: First post>, <Post: Second post>]>
340
348
341
- >>> Post.objects.filter(tags__label__overlap =["tutorial", "thoughts"])
349
+ >>> Post.objects.filter(tags__label__in =["tutorial", "thoughts"])
342
350
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
343
351
344
352
.. fieldlookup :: embeddedmodelarrayfield.len
@@ -377,45 +385,115 @@ given value. This acts like an existence filter on matching embedded documents.
377
385
>>> Post.objects.filter(tags__label__exact="tutorial")
378
386
<QuerySet [<Post: Second post>]>
379
387
380
- Note that this does **not ** require the whole array to match, only that at
381
- least one embedded document matches exactly.
388
+ .. fieldlookup :: embeddedmodelarrayfield.iexact
382
389
383
- Keytransforms
384
- ^^^^^^^^^^^^^
390
+ `` iexact ``
391
+ ^^^^^^^^^^
385
392
386
- Key transforms for :class: ` EmbeddedModelArrayField ` allow querying fields of
387
- the embedded model. The transform checks if ** any ** element in the array has a
388
- field matching the condition, similar to MongoDB behavior. For example:
393
+ Returns objects where ** any ** embedded model in the array has a field that
394
+ matches the given value ** case-insensitively **. This works like `` exact `` but
395
+ ignores letter casing.
389
396
390
397
.. code-block :: pycon
391
398
399
+
392
400
>>> Post.objects.create(
393
- ... name="First post", tags=[Tag(label="thoughts"), Tag(label="django")]
394
- ... )
395
- >>> Post.objects.create(name="Second post", tags=[Tag(label="thoughts")])
396
- >>> Post.objects.create(
397
- ... name="Third post",
398
- ... tags=[Tag(label="django"), Tag(label="python"), Tag(label="thoughts")],
401
+ ... name="First post", tags=[Tag(label="Thoughts"), Tag(label="Django")]
399
402
... )
403
+ >>> Post.objects.create(name="Second post", tags=[Tag(label="tutorial")])
400
404
401
- >>> Post.objects.filter(tags__label="django")
402
- <QuerySet [<Post: First post>, <Post: Third post>]>
405
+ >>> Post.objects.filter(tags__label__iexact="django")
406
+ <QuerySet [<Post: First post>]>
407
+
408
+ >>> Post.objects.filter(tags__label__iexact="TUTORIAL")
409
+ <QuerySet [<Post: Second post>]>
410
+
411
+ .. fieldlookup :: embeddedmodelarrayfield.gt
412
+ .. fieldlookup :: embeddedmodelarrayfield.gte
413
+ .. fieldlookup :: embeddedmodelarrayfield.lt
414
+ .. fieldlookup :: embeddedmodelarrayfield.lte
415
+
416
+ ``Greater Than, Greater Than or Equal, Less Than, Less Than or Equal ``
417
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
403
418
404
- Transforms can be chained:
419
+ These lookups return objects where **any ** embedded document contains a value
420
+ that satisfies the corresponding comparison. These are typically used on
421
+ numeric or comparable fields within the embedded model.
422
+
423
+ Examples:
405
424
406
425
.. code-block :: pycon
407
426
408
- >>> Post.objects.filter(tags__label__overlap=["django"])
409
- <QuerySet [<Post: First post>, <Post: Third post>]>
427
+ Post.objects.create(
428
+ name="First post", tags=[Tag(label="django", rating=5), Tag(label="rest", rating=3)]
429
+ )
430
+ Post.objects.create(
431
+ name="Second post", tags=[Tag(label="python", rating=2)]
432
+ )
433
+
434
+ Post.objects.filter(tags__rating__gt=3)
435
+ <QuerySet [<Post: First post>]>
436
+
437
+ Post.objects.filter(tags__rating__gte=3)
438
+ <QuerySet [<Post: First post>, <Post: Second post>]>
439
+
440
+ Post.objects.filter(tags__rating__lt=3)
441
+ <QuerySet []>
442
+
443
+ Post.objects.filter(tags__rating__lte=3)
444
+ <QuerySet [<Post: First post>, <Post: Second post>]>
445
+
446
+ .. fieldlookup :: embeddedmodelarrayfield.all
410
447
448
+ ``all ``
449
+ ^^^^^^^
450
+
451
+ Returns objects where **all ** values provided on the right-hand side are
452
+ present. It requires that *every * value be matched by some document in
453
+ the array.
411
454
412
- Indexed access is also supported :
455
+ Example :
413
456
414
457
.. code-block :: pycon
415
458
416
- >>> Post.objects.filter(tags__0__label="django")
459
+ Post.objects.create(
460
+ name="First post", tags=[Tag(label="django"), Tag(label="rest")]
461
+ )
462
+ Post.objects.create(
463
+ name="Second post", tags=[Tag(label="django")]
464
+ )
465
+
466
+ Post.objects.filter(tags__label__all=["django", "rest"])
417
467
<QuerySet [<Post: First post>]>
418
468
469
+ Post.objects.filter(tags__label__all=["django"])
470
+ <QuerySet [<Post: First post>, <Post: Second post>]>
471
+
472
+ .. fieldlookup :: embeddedmodelarrayfield.contained_by
473
+
474
+ ``contained_by ``
475
+ ^^^^^^^^^^^^^^^^
476
+
477
+ Returns objects where the embedded model array is **contained by ** the list of
478
+ values on the right-hand side. In other words, every value in the embedded
479
+ array must be present in the given list.
480
+
481
+ Example:
482
+
483
+ .. code-block :: pycon
484
+
485
+ Post.objects.create(
486
+ name="First post", tags=[Tag(label="django"), Tag(label="rest")]
487
+ )
488
+ Post.objects.create(
489
+ name="Second post", tags=[Tag(label="django")]
490
+ )
491
+
492
+ Post.objects.filter(tags__label__contained_by=["django", "rest", "api"])
493
+ <QuerySet [<Post: First post>, <Post: Second post>]>
494
+
495
+ Post.objects.filter(tags__label__contained_by=["django"])
496
+ <QuerySet [<Post: Second post>]>
419
497
420
498
``ObjectIdAutoField ``
421
499
---------------------
0 commit comments