Skip to content

Commit b45dc6f

Browse files
committed
Add docs
1 parent 42545d6 commit b45dc6f

File tree

1 file changed

+201
-0
lines changed

1 file changed

+201
-0
lines changed

docs/source/ref/models/fields.rst

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,207 @@ These indexes use 0-based indexing.
299299
As described above for :class:`EmbeddedModelField`,
300300
:djadmin:`makemigrations` does not yet detect changes to embedded models.
301301

302+
Querying ``EmbeddedModelArrayField``
303+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
304+
305+
There are a number of custom lookups and a transform for
306+
:class:`EmbeddedModelArrayField`, similar to those available
307+
for :class:`ArrayField`.
308+
We will use the following example model::
309+
310+
from django.db import models
311+
from django_mongodb_backend.fields import EmbeddedModelArrayField
312+
313+
314+
class Tag(EmbeddedModel):
315+
label = models.CharField(max_length=100)
316+
317+
class Post(models.Model):
318+
name = models.CharField(max_length=200)
319+
tags = EmbeddedModelArrayField(Tag)
320+
321+
def __str__(self):
322+
return self.name
323+
324+
Embedded field lookup
325+
^^^^^^^^^^^^^^^^^^^^^
326+
327+
Embedded field lookup for :class:`EmbeddedModelArrayField` allow querying
328+
fields of the embedded model. This is done by composing the two involved paths:
329+
the path to the ``EmbeddedModelArrayField`` and the path within the nested
330+
embedded model.
331+
This composition enables generating the appropriate query for the lookups.
332+
333+
.. fieldlookup:: embeddedmodelarrayfield.in
334+
335+
``in``
336+
^^^^^^
337+
338+
Returns objects where any of the embedded documents in the field match any of
339+
the values passed. For example:
340+
341+
.. code-block:: pycon
342+
343+
>>> Post.objects.create(
344+
... name="First post", tags=[Tag(label="thoughts"), Tag(label="django")]
345+
... )
346+
>>> Post.objects.create(name="Second post", tags=[Tag(label="thoughts")])
347+
>>> Post.objects.create(
348+
... name="Third post", tags=[Tag(label="tutorial"), Tag(label="django")]
349+
... )
350+
351+
>>> Post.objects.filter(tags__label__in=["thoughts"])
352+
<QuerySet [<Post: First post>, <Post: Second post>]>
353+
354+
>>> Post.objects.filter(tags__label__in=["tutorial", "thoughts"])
355+
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
356+
357+
.. fieldlookup:: embeddedmodelarrayfield.len
358+
359+
``len``
360+
^^^^^^^
361+
362+
Returns the length of the embedded model array. The lookups available afterward
363+
are those available for :class:`~django.db.models.IntegerField`. For example:
364+
365+
.. code-block:: pycon
366+
367+
>>> Post.objects.create(
368+
... name="First post", tags=[Tag(label="thoughts"), Tag(label="django")]
369+
... )
370+
>>> Post.objects.create(name="Second post", tags=[Tag(label="thoughts")])
371+
372+
>>> Post.objects.filter(tags__len=1)
373+
<QuerySet [<Post: Second post>]>
374+
375+
.. fieldlookup:: embeddedmodelarrayfield.exact
376+
377+
``exact``
378+
^^^^^^^^^
379+
380+
Returns objects where **any** embedded model in the array exactly matches the
381+
given value. This acts like an existence filter on matching embedded documents.
382+
383+
.. code-block:: pycon
384+
385+
>>> Post.objects.create(
386+
... name="First post", tags=[Tag(label="thoughts"), Tag(label="django")]
387+
... )
388+
>>> Post.objects.create(name="Second post", tags=[Tag(label="tutorial")])
389+
390+
>>> Post.objects.filter(tags__label__exact="tutorial")
391+
<QuerySet [<Post: Second post>]>
392+
393+
.. fieldlookup:: embeddedmodelarrayfield.iexact
394+
395+
``iexact``
396+
^^^^^^^^^^
397+
398+
Returns objects where **any** embedded model in the array has a field that
399+
matches the given value **case-insensitively**. This works like ``exact`` but
400+
ignores letter casing.
401+
402+
.. code-block:: pycon
403+
404+
405+
>>> Post.objects.create(
406+
... name="First post", tags=[Tag(label="Thoughts"), Tag(label="Django")]
407+
... )
408+
>>> Post.objects.create(name="Second post", tags=[Tag(label="tutorial")])
409+
410+
>>> Post.objects.filter(tags__label__iexact="django")
411+
<QuerySet [<Post: First post>]>
412+
413+
>>> Post.objects.filter(tags__label__iexact="TUTORIAL")
414+
<QuerySet [<Post: Second post>]>
415+
416+
.. fieldlookup:: embeddedmodelarrayfield.gt
417+
.. fieldlookup:: embeddedmodelarrayfield.gte
418+
.. fieldlookup:: embeddedmodelarrayfield.lt
419+
.. fieldlookup:: embeddedmodelarrayfield.lte
420+
421+
``Greater Than, Greater Than or Equal, Less Than, Less Than or Equal``
422+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
423+
424+
These lookups return objects where **any** embedded document contains a value
425+
that satisfies the corresponding comparison. These are typically used on
426+
numeric or comparable fields within the embedded model.
427+
428+
Examples:
429+
430+
.. code-block:: pycon
431+
432+
Post.objects.create(
433+
name="First post", tags=[Tag(label="django", rating=5), Tag(label="rest", rating=3)]
434+
)
435+
Post.objects.create(
436+
name="Second post", tags=[Tag(label="python", rating=2)]
437+
)
438+
439+
Post.objects.filter(tags__rating__gt=3)
440+
<QuerySet [<Post: First post>]>
441+
442+
Post.objects.filter(tags__rating__gte=3)
443+
<QuerySet [<Post: First post>, <Post: Second post>]>
444+
445+
Post.objects.filter(tags__rating__lt=3)
446+
<QuerySet []>
447+
448+
Post.objects.filter(tags__rating__lte=3)
449+
<QuerySet [<Post: First post>, <Post: Second post>]>
450+
451+
.. fieldlookup:: embeddedmodelarrayfield.all
452+
453+
``all``
454+
^^^^^^^
455+
456+
Returns objects where **all** values provided on the right-hand side are
457+
present. It requires that *every* value be matched by some document in
458+
the array.
459+
460+
Example:
461+
462+
.. code-block:: pycon
463+
464+
Post.objects.create(
465+
name="First post", tags=[Tag(label="django"), Tag(label="rest")]
466+
)
467+
Post.objects.create(
468+
name="Second post", tags=[Tag(label="django")]
469+
)
470+
471+
Post.objects.filter(tags__label__all=["django", "rest"])
472+
<QuerySet [<Post: First post>]>
473+
474+
Post.objects.filter(tags__label__all=["django"])
475+
<QuerySet [<Post: First post>, <Post: Second post>]>
476+
477+
.. fieldlookup:: embeddedmodelarrayfield.contained_by
478+
479+
``contained_by``
480+
^^^^^^^^^^^^^^^^
481+
482+
Returns objects where the embedded model array is **contained by** the list of
483+
values on the right-hand side. In other words, every value in the embedded
484+
array must be present in the given list.
485+
486+
Example:
487+
488+
.. code-block:: pycon
489+
490+
Post.objects.create(
491+
name="First post", tags=[Tag(label="django"), Tag(label="rest")]
492+
)
493+
Post.objects.create(
494+
name="Second post", tags=[Tag(label="django")]
495+
)
496+
497+
Post.objects.filter(tags__label__contained_by=["django", "rest", "api"])
498+
<QuerySet [<Post: First post>, <Post: Second post>]>
499+
500+
Post.objects.filter(tags__label__contained_by=["django"])
501+
<QuerySet [<Post: Second post>]>
502+
302503
``ObjectIdAutoField``
303504
---------------------
304505

0 commit comments

Comments
 (0)