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