From aeeeae1222cd379a720c9d925e6baef31b408e6d Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 14 Jan 2025 13:44:42 -0500 Subject: [PATCH 01/23] DOCSP-46425: Specify a query --- source/index.txt | 10 ++- source/interact-data/specify-a-query.txt | 90 ++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 source/interact-data/specify-a-query.txt diff --git a/source/index.txt b/source/index.txt index 2e57793..e59c4ee 100644 --- a/source/index.txt +++ b/source/index.txt @@ -2,9 +2,13 @@ Django MongoDB Backend ====================== -.. default-domain:: mongodb +.. facet:: + :name: programming_language + :values: python -Your words here. Don't forget to add a toctree! +.. meta:: + :keywords: home -Have a lovely day! +.. toctree:: + Interact with Data \ No newline at end of file diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt new file mode 100644 index 0000000..6b9b38d --- /dev/null +++ b/source/interact-data/specify-a-query.txt @@ -0,0 +1,90 @@ +.. _django-specify-query: + +=============== +Specify a Query +=============== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: expressions, operations, read, filter, code example + +Overview +-------- + +In this guide, you can learn how to use {+django-odm+} to specify +a database query. + +You can refine the set of documents that a query returns by creating a +**query filter**. A query filter is an expression that specifies the search +criteria MongoDB uses to match documents in a read or write operation. +In a query filter, you can prompt the driver to search for documents with an +exact match to your query, or you can compose query filters to express more +complex matching criteria. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``Movie`` model, which represents +the ``sample_mflix.movies`` collection from the :atlas:`Atlas sample datasets `. +The ``Movie`` model class has the following definition: + +.. code-block:: python + + from django.db import models + from django_mongodb_backend.fields import EmbeddedModelField, ArrayField + from django_mongodb_backend.managers import MongoManager + + class Movie(models.Model): + title = models.CharField(max_length=200) + plot = models.TextField(blank=True) + runtime = models.IntegerField(default=0) + released = models.DateTimeField("release date", null=True, blank=True) + awards = EmbeddedModelField(Award) + genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) + objects = MongoManager() + + class Meta: + db_table = "movies" + managed = False + + def __str__(self): + return self.title + +You can use the Python interactive shell to run the code examples. +To enter the shell, run the following command from your project's +root directory: + +.. code-block:: bash + + python manage.py shell + +To learn how to create a Django application that uses the ``Movie`` +model and the Python interactive shell to interact with MongoDB documents, +visit the :ref:`django-get-started` tutorial. + +Overview +- each query returns new instance of QuerySet class +- lazy: doesn't run query until you retrieve results + +Methods: +- all() +- filter() +- exclude() +- get() + +Modify: +- order_by() +- first() +- limit -- [5:10] + +Query filters: +- field lookups (__lt, __gt, etc; __exact, __iexact; __contains; embedded lookups; __isnull) \ No newline at end of file From 86257f0c28faa4638b16e6b004c0727994e65c69 Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 14 Jan 2025 17:52:48 -0500 Subject: [PATCH 02/23] DOCSP-46425: Specify a Query --- snooty.toml | 7 +- .../includes/interact-data/specify-a-query.py | 30 ++ source/interact-data.txt | 17 + source/interact-data/specify-a-query.txt | 323 +++++++++++++++--- 4 files changed, 335 insertions(+), 42 deletions(-) create mode 100644 source/includes/interact-data/specify-a-query.py create mode 100644 source/interact-data.txt diff --git a/snooty.toml b/snooty.toml index 7c56c09..fff2b74 100644 --- a/snooty.toml +++ b/snooty.toml @@ -7,5 +7,8 @@ intersphinx = [ "https://www.mongodb.com/docs/manual/objects.inv", # toc_landing_pages = ["/paths/to/pages/that/have/nested/content"] -# [constants] -# constant = "value" +[constants] +django-odm = "Django MongoDB Backend" +django-version = "5.0" +api = "https://django-mongodb.readthedocs.io/en/latest/" +django-docs = "https://docs.djangoproject.com/en/{+django-version+}/ref/" diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py new file mode 100644 index 0000000..9692a0e --- /dev/null +++ b/source/includes/interact-data/specify-a-query.py @@ -0,0 +1,30 @@ +# start-models +from django.db import models +from django_mongodb_backend.fields import EmbeddedModelField, ArrayField + +class Movie(models.Model): + title = models.CharField(max_length=200) + plot = models.TextField(blank=True) + runtime = models.IntegerField(default=0) + released = models.DateTimeField("release date", null=True, blank=True) + awards = EmbeddedModelField(Award) + genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) + + class Meta: + db_table = "movies" + managed = False + + def __str__(self): + return self.title + +class Award(models.Model): + wins = models.IntegerField(default=0) + nominations = models.IntegerField(default=0) + text = models.CharField(max_length=100) + + class Meta: + managed = False +# end-models + +# start-all +# end-all \ No newline at end of file diff --git a/source/interact-data.txt b/source/interact-data.txt new file mode 100644 index 0000000..f322182 --- /dev/null +++ b/source/interact-data.txt @@ -0,0 +1,17 @@ +.. _django-interact-data: + +================== +Interact with Data +================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: odm, crud, query + +.. toctree:: + :caption: Interact with Data + + Specify a Query \ No newline at end of file diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 6b9b38d..a9ae00c 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -23,10 +23,25 @@ Overview In this guide, you can learn how to use {+django-odm+} to specify a database query. +The Django ``QuerySet`` API provides functions that allow you to retrieve +model objects. To run a MongoDB database query, create a ``QuerySet`` object +that specifies your query and the model you're querying. Then, {+django-odm+} +runs the operation on the MongoDB collection that the model represents. + +When you assign a ``QuerySet`` object to a variable, {+django-odm+} does not +perform the operation until you evaluate the variable, usually by printing. After +evaluating the ``QuerySet``, Django saves the query results in the ``QuerySet`` +cache. Future evaluations of the ``QuerySet`` reuse the cached results. + +.. tip:: + + To learn more about the Django ``QuerySet`` API, see `QuerySet API reference + <{+django-docs+}/models/querysets/>`__ in the Django documentation. + You can refine the set of documents that a query returns by creating a **query filter**. A query filter is an expression that specifies the search criteria MongoDB uses to match documents in a read or write operation. -In a query filter, you can prompt the driver to search for documents with an +In a query filter, you can prompt {+django-odm+} to search for documents with an exact match to your query, or you can compose query filters to express more complex matching criteria. @@ -35,29 +50,14 @@ Sample Data The examples in this guide use the ``Movie`` model, which represents the ``sample_mflix.movies`` collection from the :atlas:`Atlas sample datasets `. -The ``Movie`` model class has the following definition: - -.. code-block:: python +The ``Movie`` model contains an embedded ``Award`` model as the value +of its ``awards`` field. These model classes have the following definitions: - from django.db import models - from django_mongodb_backend.fields import EmbeddedModelField, ArrayField - from django_mongodb_backend.managers import MongoManager - - class Movie(models.Model): - title = models.CharField(max_length=200) - plot = models.TextField(blank=True) - runtime = models.IntegerField(default=0) - released = models.DateTimeField("release date", null=True, blank=True) - awards = EmbeddedModelField(Award) - genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) - objects = MongoManager() - - class Meta: - db_table = "movies" - managed = False - - def __str__(self): - return self.title +.. literalinclude:: /includes/interact-data/specify-a-query.py + :start-after: start-models + :end-before: end-models + :language: python + :copyable: You can use the Python interactive shell to run the code examples. To enter the shell, run the following command from your project's @@ -71,20 +71,263 @@ To learn how to create a Django application that uses the ``Movie`` model and the Python interactive shell to interact with MongoDB documents, visit the :ref:`django-get-started` tutorial. -Overview -- each query returns new instance of QuerySet class -- lazy: doesn't run query until you retrieve results - -Methods: -- all() -- filter() -- exclude() -- get() - -Modify: -- order_by() -- first() -- limit -- [5:10] - -Query filters: -- field lookups (__lt, __gt, etc; __exact, __iexact; __contains; embedded lookups; __isnull) \ No newline at end of file +Run a Query +----------- + +To query your MongoDB data, call a ``QuerySet`` function on the +model that represents your collection and specify your matching +criteria in a query filter. + +This section describes how to use the following functions from +the ``QuerySet`` API: + +- :ref:`all() ` +- :ref:`filter() ` +- :ref:`get() ` +- :ref:`exclude() ` + +.. _django-query-retrieve-all: + +Retrieve All Documents +~~~~~~~~~~~~~~~~~~~~~~ + +To retrieve all documents from a collection, call the ``all()`` +method on the collection's corresponding Django model. + +The following example calls the ``all()`` method on the +``Movie`` model to retrieve all documents in the ``sample_mflix.movies`` +collection: + +.. _django-query-retrieve-matching: + +Retrieve Matching Documents +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To query a collection for documents that match a set of criteria, +call the ``filter()`` method on the collection's corresponding Django +model. Pass a query filter to the ``filter()`` method that specifies your +query criteria. + +The following example calls the ``filter()`` method on the +``Movie`` model to query the ``sample_mflix.movies`` collection +for documents that have a ``runtime`` value of ``300``: + + +.. _django-query-retrieve-one: + +Retrieve One Document +~~~~~~~~~~~~~~~~~~~~~ + +To retrieve one document from a collection, call the ``get()`` +method on the collection's corresponding Django model. Pass +a query filter to the ``get()`` method that specifies your +query criteria. + +.. important:: + + If your query matches no documents or multiple documents, the ``get()`` + method generates an error. To retrieve one document from a query + that might match multiple, use the :ref:`first() ` + method. + + +The following example calls the ``get()`` method on the +``Movie`` model to retrieve one document that has a ``title`` +value of ``"Finding Nemo"``: + + +.. _django-query-exclude: + +Exclude Matching Documents +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To query a collection for documents that do not meet your +search criteria, call the ``exclude()`` method on the collection's +corresponding Django model. Pass the exclusion criteria as an +argument to the ``exclude()`` method. + +The following example calls the ``exclude()`` method on the +``Movie`` model to exclude documents released after January 1, +1950 from the results: + +.. tip:: + + The preceding example uses the ``gt`` comparison operator + to query the collection. To learn more about comparison + operators, see the :ref:`django-query-comparison` section + in this guide. + +Customize Your Query Filter +--------------------------- + +You can further refine your query criteria by using a **field lookup** +in your query filter. Field lookups allow you to clarify the relationship +between the field you're querying and the value you want to +query for. Use the following syntax to specify a field lookup: + +.. code-block:: python + :copyable: false + + Model.objects.filter(__=) + +You can use different lookup types to perform advanced queries, +such as partial text matching, array element queries, regular +expression matching, and year value matching for datetime fields. + +.. tip:: + + To view a full list of lookup types, see `Field lookups + <{+django-docs+}/models/querysets/#field-lookups>`__ in the + ``QuerySet`` Django documentation. + +This section describes how to refine your query filters +in the following ways: + +- :ref:`django-query-text-match` +- :ref:`django-query-comparison` +- :ref:`django-query-span-relationships` + +.. _django-query-text-match: + +Use Text Match Lookups +~~~~~~~~~~~~~~~~~~~~~~ + +The following table describes some of the lookup types +that you can use to run queries that include specific +matching criteria for text values: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Lookup Type + - Description + + * - ``__exact`` + - | Specifies an exact text match. If you do not provide a + lookup type in your query filter, {+django-odm+} uses this + type by default. + + | You can specify a case-insensitive exact text match + by using ``__iexact``. + * - ``__contains`` + - | Specifies a partial text match. + + | You can specify a case-insensitive partial text match + by using ``__icontains``. + * - ``__startswith`` + - | Matches field values that begin with the specified text. + + | You can specify a case-insensitive partial text match + by using ``__istartswith``. + * - ``__endswith`` + - | Matches field values that end with the specified text. + + | You can specify a case-insensitive partial text match + by using ``__iendswith``. + +Example +``````` + +The following example uses the ``__contains`` lookup to +query for documents in which the ``genres`` array field +includes ``"Romance"``: + + +.. _django-query-comparison: + +Use Comparison Lookups +~~~~~~~~~~~~~~~~~~~~~~ + +The following table describes some of the lookup types +that you can use to run queries that include specific +matching criteria for text values: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Lookup Type + - Description + + * - ``__gt`` + - | Matches field values that are greater than the + specified value. + + * - ``__gte`` + - | Matches field values that are greater than or equal + to the specified value. + + * - ``__lt`` + - | Matches field values that are less than the specified + value. + + * - ``__lte`` + - | Matches field values that are less or equal to than the specified + value. + + * - ``__ne`` + - | Matches field values that are not equal + to the specified value. + + +Example +``````` + +The following example uses the ``__lte`` lookup to +query for documents in which the ``runtime`` value +is less than or equal to ``50``: + + +.. _django-query-span-relationships: + +Filter Across Relationships +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example retrieves all ``Entry`` objects with a ``Blog`` whose ``name`` +is ``'Beatles Blog'``: + +.. code-block:: python + + Entry.objects.filter(blog__name="Beatles Blog") + +Modify Query Results +-------------------- + +This section describes how to modify your query +results in the following ways: + +- :ref:`django-query-sort` +- :ref:`django-query-limit` +- :ref:`django-query-first` + +.. _django-query-sort: + +Sort Results +~~~~~~~~~~~~ + +.. _django-query-limit: + +Limit Results +~~~~~~~~~~~~~ + +.. _django-query-first: + +Retrieve the First Result +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +Advanced Queries +---------------- + +Query a JSONField +~~~~~~~~~~~~~~~~~ + +Query a Primary Key Field +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run a Destructive Operation +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Additional Information +---------------------- From 8e5ef5e4159ccba2dcbc6fdc92450c19ced112a4 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 15 Jan 2025 10:24:13 -0500 Subject: [PATCH 03/23] more info --- .../includes/interact-data/specify-a-query.py | 19 ++- source/interact-data/specify-a-query.txt | 130 ++++++++++++++++-- 2 files changed, 137 insertions(+), 12 deletions(-) diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index 9692a0e..e9790a8 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -27,4 +27,21 @@ class Meta: # end-models # start-all -# end-all \ No newline at end of file +Movie.objects.all() +# end-all + +# start-filter +Movie.objects.filter(runtime=300) +# end-filter + +# start-get +Movie.objects.get(title="Finding Nemo") +# end-get + +# start-exclude +Movie.objects.exclude(released__lt=timezone.make_aware(datetime(1980, 1, 1))) +# end-exclude + +# start-filter-contains +Movie.objects.filter(plot__contains="coming-of-age") +# end-filter-contains \ No newline at end of file diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index a9ae00c..8279b91 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -67,6 +67,15 @@ root directory: python manage.py shell +After entering the Python shell, ensure that you import the following models and +modules: + +.. code-block:: python + + from .models import Movie, Award + from django.utils import timezone + from datetime import datetime + To learn how to create a Django application that uses the ``Movie`` model and the Python interactive shell to interact with MongoDB documents, visit the :ref:`django-get-started` tutorial. @@ -98,6 +107,27 @@ The following example calls the ``all()`` method on the ``Movie`` model to retrieve all documents in the ``sample_mflix.movies`` collection: +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-all + :end-before: end-all + :language: python + + .. output:: + + , , + , + , , + , , + , , , + , , + , , , + , , , + , , + '...(remaining elements truncated)...']> + .. _django-query-retrieve-matching: Retrieve Matching Documents @@ -112,6 +142,18 @@ The following example calls the ``filter()`` method on the ``Movie`` model to query the ``sample_mflix.movies`` collection for documents that have a ``runtime`` value of ``300``: +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-filter + :end-before: end-filter + :language: python + + .. output:: + + , , + ]> .. _django-query-retrieve-one: @@ -135,6 +177,17 @@ The following example calls the ``get()`` method on the ``Movie`` model to retrieve one document that has a ``title`` value of ``"Finding Nemo"``: +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-get + :end-before: end-get + :language: python + + .. output:: + + .. _django-query-exclude: @@ -147,12 +200,33 @@ corresponding Django model. Pass the exclusion criteria as an argument to the ``exclude()`` method. The following example calls the ``exclude()`` method on the -``Movie`` model to exclude documents released after January 1, -1950 from the results: +``Movie`` model to exclude documents released before January 1, +1980 from the results: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-exclude + :end-before: end-exclude + :language: python + + .. output:: + + , , + , , + , , , + , , + , , + , , + , , + , , + , , + , '...(remaining elements truncated)...']> .. tip:: - The preceding example uses the ``gt`` comparison operator + The preceding example uses the ``lt`` comparison operator to query the collection. To learn more about comparison operators, see the :ref:`django-query-comparison` section in this guide. @@ -230,9 +304,28 @@ Example ``````` The following example uses the ``__contains`` lookup to -query for documents in which the ``genres`` array field -includes ``"Romance"``: +query for documents in which the ``plot`` field +includes ``"coming-of-age"``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-filter-contains + :end-before: end-filter-contains + :language: python + .. output:: + + , , + , , , + , , , + , , , + , + , , + , , , + , , , + '...(remaining elements truncated)...']> .. _django-query-comparison: @@ -278,18 +371,33 @@ The following example uses the ``__lte`` lookup to query for documents in which the ``runtime`` value is less than or equal to ``50``: +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-filter-lte + :end-before: end-filter-lte + :language: python + + .. output:: + + , , + , + , , + , , , + , , , + , , + , , , + , , + , , + '...(remaining elements truncated)...']> .. _django-query-span-relationships: Filter Across Relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This example retrieves all ``Entry`` objects with a ``Blog`` whose ``name`` -is ``'Beatles Blog'``: - -.. code-block:: python - - Entry.objects.filter(blog__name="Beatles Blog") +This example Modify Query Results -------------------- From b5ceafc0ac1f2a2621995f83a91751296da2b1c3 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 15 Jan 2025 12:42:57 -0500 Subject: [PATCH 04/23] more --- .../includes/interact-data/specify-a-query.py | 42 ++++- source/interact-data/specify-a-query.txt | 168 +++++++++++++++++- 2 files changed, 198 insertions(+), 12 deletions(-) diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index e9790a8..1e8d254 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -2,6 +2,14 @@ from django.db import models from django_mongodb_backend.fields import EmbeddedModelField, ArrayField +class Award(models.Model): + wins = models.IntegerField(default=0) + nominations = models.IntegerField(default=0) + text = models.CharField(max_length=100) + + class Meta: + managed = False + class Movie(models.Model): title = models.CharField(max_length=200) plot = models.TextField(blank=True) @@ -16,14 +24,6 @@ class Meta: def __str__(self): return self.title - -class Award(models.Model): - wins = models.IntegerField(default=0) - nominations = models.IntegerField(default=0) - text = models.CharField(max_length=100) - - class Meta: - managed = False # end-models # start-all @@ -44,4 +44,28 @@ class Meta: # start-filter-contains Movie.objects.filter(plot__contains="coming-of-age") -# end-filter-contains \ No newline at end of file +# end-filter-contains + +# start-filter-lte +Movie.objects.filter(runtime__lte=50) +# end-filter-lte + +# start-filter-relationships +Movie.objects.filter(awards__wins=93) +# end-filter-relationships + +# start-filter-combine +Movie.objects.filter(awards__text__istartswith="nominated") +# end-filter-combine + +# start-sort +Movie.objects.filter(title__startswith="Rocky").order_by("released") +# end-sort + +# start-limit +Movie.objects.filter(released=timezone.make_aware(datetime(2010, 7, 1)))[3:6] +# end-limit + +# start-first +Movie.objects.filter(genres=["Crime", "Comedy"]).first() +# end-first \ No newline at end of file diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 8279b91..c039cb9 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -304,8 +304,8 @@ Example ``````` The following example uses the ``__contains`` lookup to -query for documents in which the ``plot`` field -includes ``"coming-of-age"``: +query for documents in which the ``plot`` value +includes the text ``"coming-of-age"``: .. io-code-block:: :copyable: @@ -397,7 +397,76 @@ is less than or equal to ``50``: Filter Across Relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This example +You can run operations on your model that query fields of related +models. To query across relationships, specify each related field +name separated by double underscores (``__``) until you reach the +field you want to query, as shown in the following code: + +.. code-block:: python + :copyable: false + + Model.objects.filter(__=) + +Example +``````` + +This example uses a lookup that spans the ``Movie`` and ``Award`` +relationship. The ``Movie`` model's ``awards`` field has an +embedded ``Award`` model value, which represents the ``awards`` +object field in the MongoDB collection and its nested ``wins``, +``nominations``, and ``text`` fields. The code uses a lookup to query for +documents in which the ``awards.wins`` nested field value is ``93``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-filter-relationships + :end-before: end-filter-relationships + :language: python + + .. output:: + + , ]> + +.. _django-query-combine: + +Combine Lookups +~~~~~~~~~~~~~~~ + +You can combine field lookups to further specify your +query criteria. To combine lookups, chain each lookup +type together and separate them with a double underscore +(``__``). + +Example +``````` + +The following example combines lookup types to query for documents +in which the value of the ``awards.text`` nested field +begins with the text ``"nominated"``, instructing +{+django-odm+} to perform a case-insensitive text search: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-filter-combine + :end-before: end-filter-combine + :language: python + + .. output:: + + , , + , , , + , , + , , + , , + , , + , , + , , , + , , + '...(remaining elements truncated)...']> Modify Query Results -------------------- @@ -414,16 +483,109 @@ results in the following ways: Sort Results ~~~~~~~~~~~~ +You can provide a sort order for your query results by using the +``order_by()`` method. To specify an ascending sort based on values +of a given field, pass the field name as an argument. To specify a descending +sort, pass the field name prefixed with a minus symbol (``-``) as an argument. + +Example +``````` + +This example performs the following actions: + +- Calls the ``filter()`` method on the ``Movie`` model to query + the ``sample_mflix.movies`` collection +- Queries documents that have a ``title`` value starting + with the text ``"Rocky"`` +- Sorts the results in ascending order of their ``released`` field + values + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-sort + :end-before: end-sort + :language: python + + .. output:: + + , , , + , , , + ]> + .. _django-query-limit: Limit Results ~~~~~~~~~~~~~ +You can specify the number of results that a query returns +by using Python's array-slicing syntax, as shown +in the following code: + +.. code-block:: python + :copyable: false + + Model.objects.filter()[:] + +Replace the ```` and ```` placeholders with integer +values representing the subset of results you want to return. +The start value is non-inclusive and the end value is inclusive. + +If you omit the ```` value, the query returns each result, +beginning with the first match, until it returns the number specified +by the ```` value. + +Example +``````` + +This example performs the following actions: + +- Calls the ``filter()`` method on the ``Movie`` model to query + the ``sample_mflix.movies`` collection +- Queries documents that have a ``released`` value of + ``datetime(2010, 7, 16)`` (July 16, 2010) +- Returns the third and fourth results + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-limit + :end-before: end-limit + :language: python + + .. output:: + + , ]> + .. _django-query-first: Retrieve the First Result ~~~~~~~~~~~~~~~~~~~~~~~~~ +To retrieve the first result from a query that might match +multiple results, chain the ``first()`` method to the ``filter()`` +method. Pass a query filter to the ``filter()`` method that specifies your +query criteria. + +The following example calls the ``filter()`` and ``first()`` methods on the +``Movie`` model to query the ``sample_mflix.movies`` collection +for the first document in which the ``genres`` value is +``["Crime", "Comedy"]``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-first + :end-before: end-first + :language: python + + .. output:: + + + Advanced Queries ---------------- From 53bbe4c2306092e70322255f17ea6aa91b77d66c Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 15 Jan 2025 15:18:06 -0500 Subject: [PATCH 05/23] rest of page --- snooty.toml | 2 +- .../includes/interact-data/specify-a-query.py | 23 ++- source/interact-data/specify-a-query.txt | 152 ++++++++++++++++-- 3 files changed, 162 insertions(+), 15 deletions(-) diff --git a/snooty.toml b/snooty.toml index fff2b74..a92ccd2 100644 --- a/snooty.toml +++ b/snooty.toml @@ -11,4 +11,4 @@ intersphinx = [ "https://www.mongodb.com/docs/manual/objects.inv", django-odm = "Django MongoDB Backend" django-version = "5.0" api = "https://django-mongodb.readthedocs.io/en/latest/" -django-docs = "https://docs.djangoproject.com/en/{+django-version+}/ref/" +django-docs = "https://docs.djangoproject.com/en/{+django-version+}" diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index 1e8d254..d5b7361 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -17,6 +17,7 @@ class Movie(models.Model): released = models.DateTimeField("release date", null=True, blank=True) awards = EmbeddedModelField(Award) genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) + imdb = models.JSONField(null=True) class Meta: db_table = "movies" @@ -63,9 +64,27 @@ def __str__(self): # end-sort # start-limit -Movie.objects.filter(released=timezone.make_aware(datetime(2010, 7, 1)))[3:6] +Movie.objects.filter(released=timezone.make_aware(datetime(2010, 7, 16)))[2:4] # end-limit # start-first Movie.objects.filter(genres=["Crime", "Comedy"]).first() -# end-first \ No newline at end of file +# end-first + +# start-json +Movie.objects.filter(imdb__votes__gt=900000) +# end-json + +# start-kt +from django.db.models.fields.json import KT + +Movie.objects.annotate(score=KT("imdb__rating")).all().order_by("-score") +# end-kt + +# start-primary-key-pk +Movie.objects.get(pk=ObjectId("573a1394f29313caabce0d37")) +# end-primary-key-pk + +# start-primary-key-id +Movie.objects.get(id=ObjectId("573a1394f29313caabce0d37")) +# end-primary-key-id \ No newline at end of file diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index c039cb9..c943f94 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -116,6 +116,7 @@ collection: :language: python .. output:: + :visible: false , , , @@ -151,6 +152,7 @@ for documents that have a ``runtime`` value of ``300``: :language: python .. output:: + :visible: false , , ]> @@ -186,6 +188,7 @@ value of ``"Finding Nemo"``: :language: python .. output:: + :visible: false @@ -212,6 +215,7 @@ The following example calls the ``exclude()`` method on the :language: python .. output:: + :visible: false , , , , @@ -316,6 +320,7 @@ includes the text ``"coming-of-age"``: :language: python .. output:: + :visible: false , , , , , @@ -359,10 +364,6 @@ matching criteria for text values: - | Matches field values that are less or equal to than the specified value. - * - ``__ne`` - - | Matches field values that are not equal - to the specified value. - Example ``````` @@ -380,6 +381,7 @@ is less than or equal to ``50``: :language: python .. output:: + :visible: false , , , @@ -412,10 +414,11 @@ Example This example uses a lookup that spans the ``Movie`` and ``Award`` relationship. The ``Movie`` model's ``awards`` field has an -embedded ``Award`` model value, which represents the ``awards`` -object field in the MongoDB collection and its nested ``wins``, -``nominations``, and ``text`` fields. The code uses a lookup to query for -documents in which the ``awards.wins`` nested field value is ``93``: +embedded ``Award`` model value. This embedded model represents +the ``awards`` object field in the ``sample_mflix.movies`` collection +and its nested ``wins``, ``nominations``, and ``text`` fields. The +following code uses a lookup to query for documents in which the ``awards.wins`` +nested field value is ``93``: .. io-code-block:: :copyable: @@ -426,6 +429,7 @@ documents in which the ``awards.wins`` nested field value is ``93``: :language: python .. output:: + :visible: false , ]> @@ -456,6 +460,7 @@ begins with the text ``"nominated"``, instructing :language: python .. output:: + :visible: false , , , , , @@ -509,6 +514,7 @@ This example performs the following actions: :language: python .. output:: + :visible: false , , , , , , @@ -556,6 +562,7 @@ This example performs the following actions: :language: python .. output:: + :visible: false , ]> @@ -583,21 +590,142 @@ for the first document in which the ``genres`` value is :language: python .. output:: + :visible: false -Advanced Queries ----------------- +Advanced Field Queries +---------------------- + +This section describes how to run queries on the +following field types: + +- :ref:`JSONField ` +- :ref:`Primary Key ` + +.. _django-query-jsonfield: Query a JSONField ~~~~~~~~~~~~~~~~~ +You can query data stored in a ``JSONField`` value by using the +same syntax as show in the :ref:`django-query-span-relationships` +section. Chain each field and nested field name together, separated +by double underscores (``__``), until you reach the field you want +to query. + +The following example queries the ``imdb`` field, a ``JSONField``, +for values of its nested ``votes`` field that exceed ``900000``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-json + :end-before: end-json + :language: python + + .. output:: + :visible: false + + , , + , , , + , , + , + , , + , + , , + , , + , , , + , , + '...(remaining elements truncated)...']> + +JSONField Transforms +```````````````````` + +You can use the ``KT()`` method to specify a key, index, or path +transform of a ``JSONField``. For example, the following code uses +the ``annotate()`` and ``KT()`` methods to create a new ``score`` key, which +stores ``imdb.rating`` nested field values. Then, the code sorts +each document in the ``sample_mflix.movies`` collection by +their descending ``score`` values: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-kt + :end-before: end-kt + :language: python + + .. output:: + :visible: false + + , , , + , , + , , , + , , + , , , + , , , + , , + , , + '...(remaining elements truncated)...']> + +.. _django-query-primary-key: + Query a Primary Key Field ~~~~~~~~~~~~~~~~~~~~~~~~~ -Run a Destructive Operation -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can use the ``pk`` lookup shortcut to query primary key +values, which MongoDB stores as ``ObjectId`` values. + +The following example queries the ``sample_mflix.movies`` collection +for a document whose primary key is ``ObjectId("573a1394f29313caabce0d37")``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-primary-key-pk + :end-before: end-primary-keypk + :language: python + + .. output:: + :visible: false + + // Your ObjectId values might differ + + + +The ``Movie`` model, which represents the ``sample_mflix.movies`` collection, +uses the ``id`` field as its primary key. The following example constructs +the same query as the preceding code: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-primary-key-id + :end-before: end-primary-key-id + :language: python + + .. output:: + :visible: false + + // Your ObjectId values might differ + + Additional Information ---------------------- + +To learn how to run raw database queries using MongoDB's aggregation +pipeline syntax, rather than ``QuerySet`` API functions, see the +:ref:`django-raw-queries` guide. + +To learn how to perform other ``QuerySet`` operations, see the +:ref:`django-crud` guide. + +To learn more about Django queries, see `Making queries <{+django-docs+}/topics/db/queries>`__ +in the Django documentation. From 17b55059fe532f42f3156667b9cb13751d9cf07a Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 15 Jan 2025 15:30:41 -0500 Subject: [PATCH 06/23] edits --- source/interact-data/specify-a-query.txt | 47 +++++++++++++----------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index c943f94..5792097 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -101,9 +101,9 @@ Retrieve All Documents ~~~~~~~~~~~~~~~~~~~~~~ To retrieve all documents from a collection, call the ``all()`` -method on the collection's corresponding Django model. +function on the collection's corresponding Django model. -The following example calls the ``all()`` method on the +The following example calls the ``all()`` function on the ``Movie`` model to retrieve all documents in the ``sample_mflix.movies`` collection: @@ -135,11 +135,11 @@ Retrieve Matching Documents ~~~~~~~~~~~~~~~~~~~~~~~~~~~ To query a collection for documents that match a set of criteria, -call the ``filter()`` method on the collection's corresponding Django -model. Pass a query filter to the ``filter()`` method that specifies your +call the ``filter()`` function on the collection's corresponding Django +model. Pass a query filter to the ``filter()`` function that specifies your query criteria. -The following example calls the ``filter()`` method on the +The following example calls the ``filter()`` function on the ``Movie`` model to query the ``sample_mflix.movies`` collection for documents that have a ``runtime`` value of ``300``: @@ -163,19 +163,19 @@ Retrieve One Document ~~~~~~~~~~~~~~~~~~~~~ To retrieve one document from a collection, call the ``get()`` -method on the collection's corresponding Django model. Pass -a query filter to the ``get()`` method that specifies your +function on the collection's corresponding Django model. Pass +a query filter to the ``get()`` function that specifies your query criteria. .. important:: If your query matches no documents or multiple documents, the ``get()`` - method generates an error. To retrieve one document from a query + function generates an error. To retrieve one document from a query that might match multiple, use the :ref:`first() ` - method. + function. -The following example calls the ``get()`` method on the +The following example calls the ``get()`` function on the ``Movie`` model to retrieve one document that has a ``title`` value of ``"Finding Nemo"``: @@ -198,11 +198,11 @@ Exclude Matching Documents ~~~~~~~~~~~~~~~~~~~~~~~~~~ To query a collection for documents that do not meet your -search criteria, call the ``exclude()`` method on the collection's +search criteria, call the ``exclude()`` function on the collection's corresponding Django model. Pass the exclusion criteria as an -argument to the ``exclude()`` method. +argument to the ``exclude()`` function. -The following example calls the ``exclude()`` method on the +The following example calls the ``exclude()`` function on the ``Movie`` model to exclude documents released before January 1, 1980 from the results: @@ -489,7 +489,7 @@ Sort Results ~~~~~~~~~~~~ You can provide a sort order for your query results by using the -``order_by()`` method. To specify an ascending sort based on values +``order_by()`` function. To specify an ascending sort based on values of a given field, pass the field name as an argument. To specify a descending sort, pass the field name prefixed with a minus symbol (``-``) as an argument. @@ -498,7 +498,7 @@ Example This example performs the following actions: -- Calls the ``filter()`` method on the ``Movie`` model to query +- Calls the ``filter()`` function on the ``Movie`` model to query the ``sample_mflix.movies`` collection - Queries documents that have a ``title`` value starting with the text ``"Rocky"`` @@ -542,12 +542,15 @@ If you omit the ```` value, the query returns each result, beginning with the first match, until it returns the number specified by the ```` value. +If you omit the ```` value, the query returns each result +but skips the number of initial results specified by ````. + Example ``````` This example performs the following actions: -- Calls the ``filter()`` method on the ``Movie`` model to query +- Calls the ``filter()`` function on the ``Movie`` model to query the ``sample_mflix.movies`` collection - Queries documents that have a ``released`` value of ``datetime(2010, 7, 16)`` (July 16, 2010) @@ -572,11 +575,11 @@ Retrieve the First Result ~~~~~~~~~~~~~~~~~~~~~~~~~ To retrieve the first result from a query that might match -multiple results, chain the ``first()`` method to the ``filter()`` -method. Pass a query filter to the ``filter()`` method that specifies your +multiple results, chain the ``first()`` function to the ``filter()`` +function. Pass a query filter to the ``filter()`` function that specifies your query criteria. -The following example calls the ``filter()`` and ``first()`` methods on the +The following example calls the ``filter()`` and ``first()`` functions on the ``Movie`` model to query the ``sample_mflix.movies`` collection for the first document in which the ``genres`` value is ``["Crime", "Comedy"]``: @@ -644,9 +647,9 @@ for values of its nested ``votes`` field that exceed ``900000``: JSONField Transforms ```````````````````` -You can use the ``KT()`` method to specify a key, index, or path +You can use the ``KT()`` function to specify a key, index, or path transform of a ``JSONField``. For example, the following code uses -the ``annotate()`` and ``KT()`` methods to create a new ``score`` key, which +the ``annotate()`` and ``KT()`` functions to create a new ``score`` key, which stores ``imdb.rating`` nested field values. Then, the code sorts each document in the ``sample_mflix.movies`` collection by their descending ``score`` values: @@ -688,7 +691,7 @@ for a document whose primary key is ``ObjectId("573a1394f29313caabce0d37")``: .. input:: /includes/interact-data/specify-a-query.py :start-after: start-primary-key-pk - :end-before: end-primary-keypk + :end-before: end-primary-key-pk :language: python .. output:: From a29716ed981f26799abbddf5b65521e047a36be4 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 15 Jan 2025 15:41:58 -0500 Subject: [PATCH 07/23] link fix --- source/interact-data/specify-a-query.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 5792097..314d4a4 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -36,7 +36,7 @@ cache. Future evaluations of the ``QuerySet`` reuse the cached results. .. tip:: To learn more about the Django ``QuerySet`` API, see `QuerySet API reference - <{+django-docs+}/models/querysets/>`__ in the Django documentation. + <{+django-docs+}/ref/models/querysets/>`__ in the Django documentation. You can refine the set of documents that a query returns by creating a **query filter**. A query filter is an expression that specifies the search @@ -255,7 +255,7 @@ expression matching, and year value matching for datetime fields. .. tip:: To view a full list of lookup types, see `Field lookups - <{+django-docs+}/models/querysets/#field-lookups>`__ in the + <{+django-docs+}/ref/models/querysets/#field-lookups>`__ in the ``QuerySet`` Django documentation. This section describes how to refine your query filters From d775baf5a22be199b11fb4e5425ba2fadb72136d Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 15 Jan 2025 16:52:40 -0500 Subject: [PATCH 08/23] edits --- source/interact-data/specify-a-query.txt | 57 ++++++++++++------------ 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 314d4a4..3dbe02a 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -24,11 +24,13 @@ In this guide, you can learn how to use {+django-odm+} to specify a database query. The Django ``QuerySet`` API provides functions that allow you to retrieve -model objects. To run a MongoDB database query, create a ``QuerySet`` object -that specifies your query and the model you're querying. Then, {+django-odm+} -runs the operation on the MongoDB collection that the model represents. +model objects. To run a MongoDB database query, call ``QuerySet`` functions +on your model's ``Manager``. The ``Manager`` class handles database +operations and allows you to interact with your MongoDB data by referencing +Django models. By default, Django adds a ``Manager`` named ``objects`` +to every model class. -When you assign a ``QuerySet`` object to a variable, {+django-odm+} does not +When you assign a ``QuerySet`` to a variable, {+django-odm+} does not perform the operation until you evaluate the variable, usually by printing. After evaluating the ``QuerySet``, Django saves the query results in the ``QuerySet`` cache. Future evaluations of the ``QuerySet`` reuse the cached results. @@ -83,9 +85,9 @@ visit the :ref:`django-get-started` tutorial. Run a Query ----------- -To query your MongoDB data, call a ``QuerySet`` function on the -model that represents your collection and specify your matching -criteria in a query filter. +To query your MongoDB data, call a ``QuerySet`` function on your +model's ``Manager`` class and specify your matching criteria in a +query filter. This section describes how to use the following functions from the ``QuerySet`` API: @@ -101,11 +103,10 @@ Retrieve All Documents ~~~~~~~~~~~~~~~~~~~~~~ To retrieve all documents from a collection, call the ``all()`` -function on the collection's corresponding Django model. +function on your model's ``Manager`` class. -The following example calls the ``all()`` function on the -``Movie`` model to retrieve all documents in the ``sample_mflix.movies`` -collection: +The following example calls the ``all()`` function to retrieve +all documents in the ``sample_mflix.movies`` collection: .. io-code-block:: :copyable: @@ -135,12 +136,12 @@ Retrieve Matching Documents ~~~~~~~~~~~~~~~~~~~~~~~~~~~ To query a collection for documents that match a set of criteria, -call the ``filter()`` function on the collection's corresponding Django -model. Pass a query filter to the ``filter()`` function that specifies your +call the ``filter()`` function on your model's ``Manager`` class. +Pass a query filter to the ``filter()`` function that specifies your query criteria. -The following example calls the ``filter()`` function on the -``Movie`` model to query the ``sample_mflix.movies`` collection +The following example calls the ``filter()`` function +to query the ``sample_mflix.movies`` collection for documents that have a ``runtime`` value of ``300``: .. io-code-block:: @@ -163,7 +164,7 @@ Retrieve One Document ~~~~~~~~~~~~~~~~~~~~~ To retrieve one document from a collection, call the ``get()`` -function on the collection's corresponding Django model. Pass +function on your model's ``Manager`` class. Pass a query filter to the ``get()`` function that specifies your query criteria. @@ -175,8 +176,8 @@ query criteria. function. -The following example calls the ``get()`` function on the -``Movie`` model to retrieve one document that has a ``title`` +The following example calls the ``get()`` function +to retrieve one document that has a ``title`` value of ``"Finding Nemo"``: .. io-code-block:: @@ -198,13 +199,12 @@ Exclude Matching Documents ~~~~~~~~~~~~~~~~~~~~~~~~~~ To query a collection for documents that do not meet your -search criteria, call the ``exclude()`` function on the collection's -corresponding Django model. Pass the exclusion criteria as an +search criteria, call the ``exclude()`` function on your model's +``Manager`` class. Pass the exclusion criteria as an argument to the ``exclude()`` function. -The following example calls the ``exclude()`` function on the -``Movie`` model to exclude documents released before January 1, -1980 from the results: +The following example calls the ``exclude()`` function to +exclude documents released before January 1, 1980 from the results: .. io-code-block:: :copyable: @@ -498,7 +498,7 @@ Example This example performs the following actions: -- Calls the ``filter()`` function on the ``Movie`` model to query +- Calls the ``filter()`` function on the ``Movie`` model's ``Manager`` to query the ``sample_mflix.movies`` collection - Queries documents that have a ``title`` value starting with the text ``"Rocky"`` @@ -550,7 +550,7 @@ Example This example performs the following actions: -- Calls the ``filter()`` function on the ``Movie`` model to query +- Calls the ``filter()`` function on the ``Movie`` model's ``Manager`` to query the ``sample_mflix.movies`` collection - Queries documents that have a ``released`` value of ``datetime(2010, 7, 16)`` (July 16, 2010) @@ -579,10 +579,9 @@ multiple results, chain the ``first()`` function to the ``filter()`` function. Pass a query filter to the ``filter()`` function that specifies your query criteria. -The following example calls the ``filter()`` and ``first()`` functions on the -``Movie`` model to query the ``sample_mflix.movies`` collection -for the first document in which the ``genres`` value is -``["Crime", "Comedy"]``: +The following example calls the ``filter()`` and ``first()`` functions +to query the ``sample_mflix.movies`` collection for the first +document in which the ``genres`` value is ``["Crime", "Comedy"]``: .. io-code-block:: :copyable: From 1e7fe901b450cbb456f8dd382dbfedfbcff2005f Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 15 Jan 2025 17:50:32 -0500 Subject: [PATCH 09/23] edits --- source/includes/interact-data/specify-a-query.py | 4 ++++ source/interact-data/specify-a-query.txt | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index d5b7361..61698bf 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -82,9 +82,13 @@ def __str__(self): # end-kt # start-primary-key-pk +from bson import ObjectId + Movie.objects.get(pk=ObjectId("573a1394f29313caabce0d37")) # end-primary-key-pk # start-primary-key-id +from bson import ObjectId + Movie.objects.get(id=ObjectId("573a1394f29313caabce0d37")) # end-primary-key-id \ No newline at end of file diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 3dbe02a..63b6704 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -230,9 +230,9 @@ exclude documents released before January 1, 1980 from the results: .. tip:: - The preceding example uses the ``lt`` comparison operator + The preceding example uses the ``lt`` field lookup to query the collection. To learn more about comparison - operators, see the :ref:`django-query-comparison` section + lookups, see the :ref:`django-query-comparison` section in this guide. Customize Your Query Filter @@ -320,6 +320,7 @@ includes the text ``"coming-of-age"``: :language: python .. output:: + :language: none :visible: false , , From 24803b2824f47f95a227388a6dddf24e842ad93a Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 16 Jan 2025 15:19:40 -0500 Subject: [PATCH 10/23] feedback --- .../includes/interact-data/specify-a-query.py | 8 +- source/interact-data/specify-a-query.txt | 271 ++++++++++++------ 2 files changed, 186 insertions(+), 93 deletions(-) diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index 61698bf..7e65925 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -56,7 +56,9 @@ def __str__(self): # end-filter-relationships # start-filter-combine -Movie.objects.filter(awards__text__istartswith="nominated") +Movie.objects.filter( + (Q(title__startswith="Funny") | Q(title__startswith="Laugh")) + & ~Q(genres__contains=["Comedy"])) # end-filter-combine # start-sort @@ -71,6 +73,10 @@ def __str__(self): Movie.objects.filter(genres=["Crime", "Comedy"]).first() # end-first +# start-array +Movie.objects.filter(genres__overlap=["Adventure", "Family"]) +# end-array + # start-json Movie.objects.filter(imdb__votes__gt=900000) # end-json diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 63b6704..adc727a 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -23,15 +23,15 @@ Overview In this guide, you can learn how to use {+django-odm+} to specify a database query. -The Django ``QuerySet`` API provides functions that allow you to retrieve -model objects. To run a MongoDB database query, call ``QuerySet`` functions +The Django ``QuerySet`` API provides methods that allow you to retrieve +model objects. To run a MongoDB database query, call ``QuerySet`` methods on your model's ``Manager``. The ``Manager`` class handles database operations and allows you to interact with your MongoDB data by referencing Django models. By default, Django adds a ``Manager`` named ``objects`` to every model class. When you assign a ``QuerySet`` to a variable, {+django-odm+} does not -perform the operation until you evaluate the variable, usually by printing. After +perform the operation until you evaluate the variable. After evaluating the ``QuerySet``, Django saves the query results in the ``QuerySet`` cache. Future evaluations of the ``QuerySet`` reuse the cached results. @@ -85,11 +85,11 @@ visit the :ref:`django-get-started` tutorial. Run a Query ----------- -To query your MongoDB data, call a ``QuerySet`` function on your +To query your MongoDB data, call a ``QuerySet`` method on your model's ``Manager`` class and specify your matching criteria in a query filter. -This section describes how to use the following functions from +This section describes how to use the following methods from the ``QuerySet`` API: - :ref:`all() ` @@ -103,9 +103,9 @@ Retrieve All Documents ~~~~~~~~~~~~~~~~~~~~~~ To retrieve all documents from a collection, call the ``all()`` -function on your model's ``Manager`` class. +method on your model's ``Manager`` class. -The following example calls the ``all()`` function to retrieve +The following example calls the ``all()`` method to retrieve all documents in the ``sample_mflix.movies`` collection: .. io-code-block:: @@ -136,11 +136,11 @@ Retrieve Matching Documents ~~~~~~~~~~~~~~~~~~~~~~~~~~~ To query a collection for documents that match a set of criteria, -call the ``filter()`` function on your model's ``Manager`` class. -Pass a query filter to the ``filter()`` function that specifies your +call the ``filter()`` method on your model's ``Manager`` class. +Pass a query filter to the ``filter()`` method that specifies your query criteria. -The following example calls the ``filter()`` function +The following example calls the ``filter()`` method to query the ``sample_mflix.movies`` collection for documents that have a ``runtime`` value of ``300``: @@ -164,19 +164,19 @@ Retrieve One Document ~~~~~~~~~~~~~~~~~~~~~ To retrieve one document from a collection, call the ``get()`` -function on your model's ``Manager`` class. Pass -a query filter to the ``get()`` function that specifies your +method on your model's ``Manager`` class. Pass +a query filter to the ``get()`` method that specifies your query criteria. .. important:: If your query matches no documents or multiple documents, the ``get()`` - function generates an error. To retrieve one document from a query + method generates an error. To retrieve one document from a query that might match multiple, use the :ref:`first() ` - function. + method. -The following example calls the ``get()`` function +The following example calls the ``get()`` method to retrieve one document that has a ``title`` value of ``"Finding Nemo"``: @@ -199,11 +199,11 @@ Exclude Matching Documents ~~~~~~~~~~~~~~~~~~~~~~~~~~ To query a collection for documents that do not meet your -search criteria, call the ``exclude()`` function on your model's +search criteria, call the ``exclude()`` method on your model's ``Manager`` class. Pass the exclusion criteria as an -argument to the ``exclude()`` function. +argument to the ``exclude()`` method. -The following example calls the ``exclude()`` function to +The following example calls the ``exclude()`` method to exclude documents released before January 1, 1980 from the results: .. io-code-block:: @@ -320,7 +320,6 @@ includes the text ``"coming-of-age"``: :language: python .. output:: - :language: none :visible: false , , @@ -339,8 +338,8 @@ Use Comparison Lookups ~~~~~~~~~~~~~~~~~~~~~~ The following table describes some of the lookup types -that you can use to run queries that include specific -matching criteria for text values: +that you can use to run queries that evaluate a field value +against a specified value: .. list-table:: :header-rows: 1 @@ -395,62 +394,39 @@ is less than or equal to ``50``: , , '...(remaining elements truncated)...']> -.. _django-query-span-relationships: - -Filter Across Relationships -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can run operations on your model that query fields of related -models. To query across relationships, specify each related field -name separated by double underscores (``__``) until you reach the -field you want to query, as shown in the following code: - -.. code-block:: python - :copyable: false - - Model.objects.filter(__=) - -Example -``````` - -This example uses a lookup that spans the ``Movie`` and ``Award`` -relationship. The ``Movie`` model's ``awards`` field has an -embedded ``Award`` model value. This embedded model represents -the ``awards`` object field in the ``sample_mflix.movies`` collection -and its nested ``wins``, ``nominations``, and ``text`` fields. The -following code uses a lookup to query for documents in which the ``awards.wins`` -nested field value is ``93``: - -.. io-code-block:: - :copyable: - - .. input:: /includes/interact-data/specify-a-query.py - :start-after: start-filter-relationships - :end-before: end-filter-relationships - :language: python - - .. output:: - :visible: false - , ]> .. _django-query-combine: Combine Lookups ~~~~~~~~~~~~~~~ -You can combine field lookups to further specify your -query criteria. To combine lookups, chain each lookup -type together and separate them with a double underscore -(``__``). +You can use ``Q`` objects to create query filters with multiple +sets of matching criteria. To create a ``Q`` object, pass your query +filter to the ``Q()`` method. You can pass multiple ``Q`` objects as +arguments to your query method and separate each Q object by an OR +(``|``), AND (``&``), or NOT (``^``) operator. You can also negate +``Q`` objects by prefixing them with the ``~`` symbol. The following example +shows the syntax for passing multiple ``Q`` objects to the ``filter()`` +method: + + +.. code-block:: python + :copyable: false + + Model.objects.filter( + Q(__=) Q(__=) + ) Example ``````` -The following example combines lookup types to query for documents -in which the value of the ``awards.text`` nested field -begins with the text ``"nominated"``, instructing -{+django-odm+} to perform a case-insensitive text search: +This example uses ``Q`` objects to query for documents +that meet the following query conditions: + +- ``title`` field value begins either with the text ``"Funny"`` + or ``"Laugh"`` +- ``genres`` array field does not contain the value ``"Comedy"`` .. io-code-block:: :copyable: @@ -463,16 +439,14 @@ begins with the text ``"nominated"``, instructing .. output:: :visible: false - , , - , , , - , , - , , - , , - , , - , , - , , , - , , - '...(remaining elements truncated)...']> + , ]> + +.. tip:: + + The preceding example uses a field lookup on an + ``ArrayField`` value. For more information about querying + an ``ArrayField``, see the :ref:`django-query-arrayfield` + section in this guide. Modify Query Results -------------------- @@ -490,7 +464,7 @@ Sort Results ~~~~~~~~~~~~ You can provide a sort order for your query results by using the -``order_by()`` function. To specify an ascending sort based on values +``order_by()`` method. To specify an ascending sort based on values of a given field, pass the field name as an argument. To specify a descending sort, pass the field name prefixed with a minus symbol (``-``) as an argument. @@ -499,7 +473,7 @@ Example This example performs the following actions: -- Calls the ``filter()`` function on the ``Movie`` model's ``Manager`` to query +- Calls the ``filter()`` method on the ``Movie`` model's ``Manager`` to query the ``sample_mflix.movies`` collection - Queries documents that have a ``title`` value starting with the text ``"Rocky"`` @@ -551,7 +525,7 @@ Example This example performs the following actions: -- Calls the ``filter()`` function on the ``Movie`` model's ``Manager`` to query +- Calls the ``filter()`` method on the ``Movie`` model's ``Manager`` to query the ``sample_mflix.movies`` collection - Queries documents that have a ``released`` value of ``datetime(2010, 7, 16)`` (July 16, 2010) @@ -576,11 +550,11 @@ Retrieve the First Result ~~~~~~~~~~~~~~~~~~~~~~~~~ To retrieve the first result from a query that might match -multiple results, chain the ``first()`` function to the ``filter()`` -function. Pass a query filter to the ``filter()`` function that specifies your +multiple results, chain the ``first()`` method to the ``filter()`` +method. Pass a query filter to the ``filter()`` method that specifies your query criteria. -The following example calls the ``filter()`` and ``first()`` functions +The following example calls the ``filter()`` and ``first()`` methods to query the ``sample_mflix.movies`` collection for the first document in which the ``genres`` value is ``["Crime", "Comedy"]``: @@ -604,16 +578,116 @@ Advanced Field Queries This section describes how to run queries on the following field types: +- :ref:`EmbeddedModelField ` - :ref:`JSONField ` - :ref:`Primary Key ` +.. _django-query-embedded: + +Query an EmbeddedModelField +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can run operations on your model that query fields of embedded +models. To query these fields, specify your model field and each embedded field +name separated by double underscores (``__``) until you reach the +field you want to query, as shown in the following code: + +.. code-block:: python + :copyable: false + + Model.objects.filter(__=) + +Example +``````` + +This example uses a lookup that spans the ``Movie`` and ``Award`` +relationship. The ``Movie`` model's ``awards`` field has an +embedded ``Award`` model value. This embedded model represents +the ``awards`` object field in the ``sample_mflix.movies`` collection +and its nested ``wins``, ``nominations``, and ``text`` fields. The +following code uses a lookup to query for documents in which the ``awards.wins`` +nested field value is ``93``: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-filter-relationships + :end-before: end-filter-relationships + :language: python + + .. output:: + :visible: false + + , ]> + +.. _django-query-arrayfield: + +Query an ArrayField +~~~~~~~~~~~~~~~~~ + +You can query data stored in an ``ArrayField`` value +by using the standard query syntax. {+django-odm+} provides +additional field lookup types for querying ``ArrayField`` values, +as described in the following table: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Lookup Type + - Description + + * - ``__contains`` + - | Matches fields that store the provided value as + a subset of their data. This ``ArrayField`` lookup overrides the + ``__contains`` lookup described in the :ref:`django-query-text-match` + section of this guide. + + * - ``__contained_by`` + - | Matches fields that store a subset of the provided values. + This lookup type is the inverse of ``__contains``. + + * - ``__overlap`` + - | Matches field that store any of the provided values. + + * - ``__len`` + - | Matches fields that store the number of values provided. + +Example +``````` + +The following example uses the ``__overlap`` lookup to query +for documents whose ``genres`` field stores any values in the +``["Adventure", "Family"]`` array: + +.. io-code-block:: + :copyable: + + .. input:: /includes/interact-data/specify-a-query.py + :start-after: start-array + :end-before: end-array + :language: python + + .. output:: + :visible: false + + , , + , , , + , , , + , , , + , , , + , , , + , , , + '...(remaining elements truncated)...']> + .. _django-query-jsonfield: Query a JSONField ~~~~~~~~~~~~~~~~~ You can query data stored in a ``JSONField`` value by using the -same syntax as show in the :ref:`django-query-span-relationships` +same syntax as show in the :ref:`django-query-embedded` section. Chain each field and nested field name together, separated by double underscores (``__``), until you reach the field you want to query. @@ -644,15 +718,28 @@ for values of its nested ``votes`` field that exceed ``900000``: , , '...(remaining elements truncated)...']> -JSONField Transforms -```````````````````` +Annotate and Filter JSON Data +````````````````````````````` + +You can use ``KT()`` expressions to annotate and filter +data stored in a ``JSONField`` value. ``KT()`` expressions allow you to +work with the text value of keys, indexes, or path transforms +within a ``JSONField``. Pass your ``KT()`` expression to the ``annotate()`` +method, which annotates each object in the ``QuerySet`` with the +provided ``KT()`` expressions. + +.. tip:: + + To learn more about ``KT()`` expressions and the ``annotate()`` method, + see the following resources in the Django documentation: + + - `KT() expressions <{+django-docs+}/topics/db/queries/#module-django.db.models.fields.json>`__ + - `annotate() <{+django-docs+}/models/querysets/#django.db.models.query.QuerySet.annotate>`__ -You can use the ``KT()`` function to specify a key, index, or path -transform of a ``JSONField``. For example, the following code uses -the ``annotate()`` and ``KT()`` functions to create a new ``score`` key, which -stores ``imdb.rating`` nested field values. Then, the code sorts -each document in the ``sample_mflix.movies`` collection by -their descending ``score`` values: +The following example uses ``annotate()`` and ``KT()`` to create a +new ``score`` key, which stores ``imdb.rating`` nested field values. +Then, the code sorts each document in the ``sample_mflix.movies`` collection +by their descending ``score`` values: .. io-code-block:: :copyable: @@ -724,7 +811,7 @@ Additional Information ---------------------- To learn how to run raw database queries using MongoDB's aggregation -pipeline syntax, rather than ``QuerySet`` API functions, see the +pipeline syntax, rather than ``QuerySet`` API methods, see the :ref:`django-raw-queries` guide. To learn how to perform other ``QuerySet`` operations, see the From 9628ae2dc72875a4730bcbb9b6a307bc4211518a Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 16 Jan 2025 15:31:06 -0500 Subject: [PATCH 11/23] fixes --- source/index.txt | 11 +++++------ source/interact-data/specify-a-query.txt | 5 ++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/source/index.txt b/source/index.txt index ea41052..970ad70 100644 --- a/source/index.txt +++ b/source/index.txt @@ -11,14 +11,13 @@ Django MongoDB Backend .. toctree:: + Interact with Data Issues & Help Compatibility - .. TODO: Get Started Connection Configuration - Interact with Data Model Your Data Django Feature Limitations API Documentation <{+api+}> @@ -43,11 +42,11 @@ a Django database backend that uses PyMongo to connect to MongoDB. .. Learn how to configure a connection to a MongoDB deployment in the :ref:`django-connection-configuration` section. -.. Interact with Data -.. ------------------ +Interact with Data +------------------ -.. Learn how to use {+django-odm+} to perform operations on MongoDB data - in the :ref:`django-interact-data` section. +Learn how to use {+django-odm+} to perform operations on MongoDB data +in the :ref:`django-interact-data` section. .. Model Your Data .. --------------- diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index adc727a..e0be686 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -263,7 +263,7 @@ in the following ways: - :ref:`django-query-text-match` - :ref:`django-query-comparison` -- :ref:`django-query-span-relationships` +- :ref:`django-query-combine` .. _django-query-text-match: @@ -394,8 +394,6 @@ is less than or equal to ``50``: , , '...(remaining elements truncated)...']> - - .. _django-query-combine: Combine Lookups @@ -579,6 +577,7 @@ This section describes how to run queries on the following field types: - :ref:`EmbeddedModelField ` +- :ref:`ArrayField ` - :ref:`JSONField ` - :ref:`Primary Key ` From eae953b1af9308aeca7e1953063c2a3b07739679 Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 16 Jan 2025 15:37:31 -0500 Subject: [PATCH 12/23] edits --- source/interact-data/specify-a-query.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index e0be686..19434b9 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -403,7 +403,7 @@ You can use ``Q`` objects to create query filters with multiple sets of matching criteria. To create a ``Q`` object, pass your query filter to the ``Q()`` method. You can pass multiple ``Q`` objects as arguments to your query method and separate each Q object by an OR -(``|``), AND (``&``), or NOT (``^``) operator. You can also negate +(``|``), AND (``&``), or XOR (``^``) operator. You can also negate ``Q`` objects by prefixing them with the ``~`` symbol. The following example shows the syntax for passing multiple ``Q`` objects to the ``filter()`` method: @@ -733,7 +733,7 @@ provided ``KT()`` expressions. see the following resources in the Django documentation: - `KT() expressions <{+django-docs+}/topics/db/queries/#module-django.db.models.fields.json>`__ - - `annotate() <{+django-docs+}/models/querysets/#django.db.models.query.QuerySet.annotate>`__ + - `annotate() <{+django-docs+}/ref/models/querysets/#django.db.models.query.QuerySet.annotate>`__ The following example uses ``annotate()`` and ``KT()`` to create a new ``score`` key, which stores ``imdb.rating`` nested field values. From 0c4d8ed6bbbce5b7947ba6bce0f3288733ac9bf5 Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 16 Jan 2025 16:04:22 -0500 Subject: [PATCH 13/23] wording --- source/interact-data/specify-a-query.txt | 28 ++++++++---------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 19434b9..98a2a84 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -399,10 +399,10 @@ is less than or equal to ``50``: Combine Lookups ~~~~~~~~~~~~~~~ -You can use ``Q`` objects to create query filters with multiple +You can use ``Q`` objects to run queries with multiple sets of matching criteria. To create a ``Q`` object, pass your query filter to the ``Q()`` method. You can pass multiple ``Q`` objects as -arguments to your query method and separate each Q object by an OR +arguments to your query method and separate each ``Q`` object by an OR (``|``), AND (``&``), or XOR (``^``) operator. You can also negate ``Q`` objects by prefixing them with the ``~`` symbol. The following example shows the syntax for passing multiple ``Q`` objects to the ``filter()`` @@ -791,27 +791,17 @@ The ``Movie`` model, which represents the ``sample_mflix.movies`` collection, uses the ``id`` field as its primary key. The following example constructs the same query as the preceding code: -.. io-code-block:: - :copyable: - - .. input:: /includes/interact-data/specify-a-query.py - :start-after: start-primary-key-id - :end-before: end-primary-key-id - :language: python - - .. output:: - :visible: false - - // Your ObjectId values might differ - - +.. literalinclude:: /includes/interact-data/specify-a-query.py + :language: python + :dedent: + :start-after: start-primary-key-id + :end-before: end-primary-key-id Additional Information ---------------------- -To learn how to run raw database queries using MongoDB's aggregation -pipeline syntax, rather than ``QuerySet`` API methods, see the -:ref:`django-raw-queries` guide. +To learn how to run raw database queries by using MongoDB's aggregation +pipeline syntax, see the :ref:`django-raw-queries` guide. To learn how to perform other ``QuerySet`` operations, see the :ref:`django-crud` guide. From a1f66130766ebb85aef9b7241f1b5e89147751cc Mon Sep 17 00:00:00 2001 From: norareidy Date: Tue, 21 Jan 2025 10:23:23 -0500 Subject: [PATCH 14/23] feedback --- source/interact-data/specify-a-query.txt | 50 +++++++++++++++++------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 98a2a84..0bba8c6 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -96,6 +96,7 @@ the ``QuerySet`` API: - :ref:`filter() ` - :ref:`get() ` - :ref:`exclude() ` +- :ref:`raw_aggregate() ` .. _django-query-retrieve-all: @@ -235,6 +236,20 @@ exclude documents released before January 1, 1980 from the results: lookups, see the :ref:`django-query-comparison` section in this guide. +.. _django-query-raw: + +Run Raw Database Queries +~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to run complex queries that Django's query API +cannot express, you can use the ``raw_aggregate()`` method. This +method allows you to specify your query criteria in a MongoDB +aggregation pipeline, which you pass as an argument to +``raw_aggregate()``. + +To learn how to run raw database queries, see the :ref:`django-raw-queries` +guide. + Customize Your Query Filter --------------------------- @@ -399,25 +414,32 @@ is less than or equal to ``50``: Combine Lookups ~~~~~~~~~~~~~~~ +You can run queries that use multiple sets of matching criteria +in the following ways: + +- Pass multiple query filters to your query method, separated + by commas. To view an example, see `Retrieving objects + <{+django-docs+}/topics/db/queries/#retrieving-objects>`__ in the + Django documentation. + +- Chain query methods together. To learn more, see `Chaining filters + <{+django-docs+}/topics/db/queries/#chaining-filters>`__ in the Django + documentation. + +- Use ``Q`` objects and separate each object with a logical operator. + To learn more, see `Complex lookups with Q objects + <{+django-docs+}/topics/db/queries/#complex-lookups-with-q-objects>`__ in the Django + documentation. + +Q Object Example +```````````````` + You can use ``Q`` objects to run queries with multiple sets of matching criteria. To create a ``Q`` object, pass your query filter to the ``Q()`` method. You can pass multiple ``Q`` objects as arguments to your query method and separate each ``Q`` object by an OR (``|``), AND (``&``), or XOR (``^``) operator. You can also negate -``Q`` objects by prefixing them with the ``~`` symbol. The following example -shows the syntax for passing multiple ``Q`` objects to the ``filter()`` -method: - - -.. code-block:: python - :copyable: false - - Model.objects.filter( - Q(__=) Q(__=) - ) - -Example -``````` +``Q`` objects by prefixing them with the ``~`` symbol. This example uses ``Q`` objects to query for documents that meet the following query conditions: From cde657c3fbd2190239be32b4b1a7323ed19a2b93 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 17:28:18 -0500 Subject: [PATCH 15/23] RR feedback --- .../includes/interact-data/specify-a-query.py | 8 +- source/interact-data/specify-a-query.txt | 131 ++++++++++-------- 2 files changed, 76 insertions(+), 63 deletions(-) diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index 7e65925..45de121 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -51,10 +51,6 @@ def __str__(self): Movie.objects.filter(runtime__lte=50) # end-filter-lte -# start-filter-relationships -Movie.objects.filter(awards__wins=93) -# end-filter-relationships - # start-filter-combine Movie.objects.filter( (Q(title__startswith="Funny") | Q(title__startswith="Laugh")) @@ -73,6 +69,10 @@ def __str__(self): Movie.objects.filter(genres=["Crime", "Comedy"]).first() # end-first +# start-filter-relationships +Movie.objects.filter(awards__wins__gt=150) +# end-filter-relationships + # start-array Movie.objects.filter(genres__overlap=["Adventure", "Family"]) # end-array diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 0bba8c6..998c8b5 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -23,9 +23,19 @@ Overview In this guide, you can learn how to use {+django-odm+} to specify a database query. +You can refine the set of documents that a query returns by creating a +**query filter**. A query filter is an expression that specifies the search +criteria MongoDB uses to match documents in a read or write operation. +In a query filter, you can prompt {+django-odm+} to search for documents with an +exact match to your query, or you can compose query filters to express more +complex matching criteria. + +Query API +~~~~~~~~~ + The Django ``QuerySet`` API provides methods that allow you to retrieve model objects. To run a MongoDB database query, call ``QuerySet`` methods -on your model's ``Manager``. The ``Manager`` class handles database +on your model's manager. The ``Manager`` class handles database operations and allows you to interact with your MongoDB data by referencing Django models. By default, Django adds a ``Manager`` named ``objects`` to every model class. @@ -33,19 +43,12 @@ to every model class. When you assign a ``QuerySet`` to a variable, {+django-odm+} does not perform the operation until you evaluate the variable. After evaluating the ``QuerySet``, Django saves the query results in the ``QuerySet`` -cache. Future evaluations of the ``QuerySet`` reuse the cached results. +cache. Future evaluations of the ``QuerySet`` use the cached results. .. tip:: - To learn more about the Django ``QuerySet`` API, see `QuerySet API reference - <{+django-docs+}/ref/models/querysets/>`__ in the Django documentation. - -You can refine the set of documents that a query returns by creating a -**query filter**. A query filter is an expression that specifies the search -criteria MongoDB uses to match documents in a read or write operation. -In a query filter, you can prompt {+django-odm+} to search for documents with an -exact match to your query, or you can compose query filters to express more -complex matching criteria. + To learn more about the Django ``QuerySet`` API, see `QuerySet API reference + <{+django-docs+}/ref/models/querysets/>`__ in the Django documentation. Sample Data ~~~~~~~~~~~ @@ -86,7 +89,7 @@ Run a Query ----------- To query your MongoDB data, call a ``QuerySet`` method on your -model's ``Manager`` class and specify your matching criteria in a +model's manager and specify your matching criteria in a query filter. This section describes how to use the following methods from @@ -104,7 +107,7 @@ Retrieve All Documents ~~~~~~~~~~~~~~~~~~~~~~ To retrieve all documents from a collection, call the ``all()`` -method on your model's ``Manager`` class. +method on your model's manager. The following example calls the ``all()`` method to retrieve all documents in the ``sample_mflix.movies`` collection: @@ -137,7 +140,7 @@ Retrieve Matching Documents ~~~~~~~~~~~~~~~~~~~~~~~~~~~ To query a collection for documents that match a set of criteria, -call the ``filter()`` method on your model's ``Manager`` class. +call the ``filter()`` method on your model's manager. Pass a query filter to the ``filter()`` method that specifies your query criteria. @@ -165,9 +168,8 @@ Retrieve One Document ~~~~~~~~~~~~~~~~~~~~~ To retrieve one document from a collection, call the ``get()`` -method on your model's ``Manager`` class. Pass -a query filter to the ``get()`` method that specifies your -query criteria. +method on your model's manager. Pass a query filter to +the ``get()`` method that specifies your query criteria. .. important:: @@ -176,7 +178,6 @@ query criteria. that might match multiple, use the :ref:`first() ` method. - The following example calls the ``get()`` method to retrieve one document that has a ``title`` value of ``"Finding Nemo"``: @@ -242,13 +243,15 @@ Run Raw Database Queries ~~~~~~~~~~~~~~~~~~~~~~~~ If you want to run complex queries that Django's query API -cannot express, you can use the ``raw_aggregate()`` method. This +does not support, you can use the ``raw_aggregate()`` method. This method allows you to specify your query criteria in a MongoDB aggregation pipeline, which you pass as an argument to ``raw_aggregate()``. -To learn how to run raw database queries, see the :ref:`django-raw-queries` -guide. +.. TODO: To learn how to run raw database queries, see the :ref:`django-raw-queries` + guide. + +.. _django-query-filter: Customize Your Query Filter --------------------------- @@ -271,7 +274,7 @@ expression matching, and year value matching for datetime fields. To view a full list of lookup types, see `Field lookups <{+django-docs+}/ref/models/querysets/#field-lookups>`__ in the - ``QuerySet`` Django documentation. + ``QuerySet`` Django API reference. This section describes how to refine your query filters in the following ways: @@ -296,33 +299,33 @@ matching criteria for text values: * - Lookup Type - Description - * - ``__exact`` + * - ``exact`` - | Specifies an exact text match. If you do not provide a lookup type in your query filter, {+django-odm+} uses this type by default. | You can specify a case-insensitive exact text match - by using ``__iexact``. - * - ``__contains`` + by using ``iexact``. + * - ``contains`` - | Specifies a partial text match. | You can specify a case-insensitive partial text match - by using ``__icontains``. - * - ``__startswith`` + by using ``icontains``. + * - ``startswith`` - | Matches field values that begin with the specified text. | You can specify a case-insensitive partial text match - by using ``__istartswith``. - * - ``__endswith`` + by using ``istartswith``. + * - ``endswith`` - | Matches field values that end with the specified text. | You can specify a case-insensitive partial text match - by using ``__iendswith``. + by using ``iendswith``. Example ``````` -The following example uses the ``__contains`` lookup to +The following example uses the ``contains`` lookup to query for documents in which the ``plot`` value includes the text ``"coming-of-age"``: @@ -363,19 +366,19 @@ against a specified value: * - Lookup Type - Description - * - ``__gt`` + * - ``gt`` - | Matches field values that are greater than the specified value. - * - ``__gte`` + * - ``gte`` - | Matches field values that are greater than or equal to the specified value. - * - ``__lt`` + * - ``lt`` - | Matches field values that are less than the specified value. - * - ``__lte`` + * - ``lte`` - | Matches field values that are less or equal to than the specified value. @@ -383,7 +386,7 @@ against a specified value: Example ``````` -The following example uses the ``__lte`` lookup to +The following example uses the ``lte`` lookup to query for documents in which the ``runtime`` value is less than or equal to ``50``: @@ -488,12 +491,15 @@ You can provide a sort order for your query results by using the of a given field, pass the field name as an argument. To specify a descending sort, pass the field name prefixed with a minus symbol (``-``) as an argument. +You can pass multiple field names, separated by commas, to the ``order_by()`` method. +{+django-odm+} sorts results by each field in the order provided. + Example ``````` This example performs the following actions: -- Calls the ``filter()`` method on the ``Movie`` model's ``Manager`` to query +- Calls the ``filter()`` method on the ``Movie`` model's manager to query the ``sample_mflix.movies`` collection - Queries documents that have a ``title`` value starting with the text ``"Rocky"`` @@ -517,8 +523,8 @@ This example performs the following actions: .. _django-query-limit: -Limit Results -~~~~~~~~~~~~~ +Skip and Limit Results +~~~~~~~~~~~~~~~~~~~~~~ You can specify the number of results that a query returns by using Python's array-slicing syntax, as shown @@ -531,7 +537,7 @@ in the following code: Replace the ```` and ```` placeholders with integer values representing the subset of results you want to return. -The start value is non-inclusive and the end value is inclusive. +The start value is exclusive and the end value is inclusive. If you omit the ```` value, the query returns each result, beginning with the first match, until it returns the number specified @@ -618,16 +624,19 @@ field you want to query, as shown in the following code: Model.objects.filter(__=) +You can also use :ref:`field lookups ` to refine +your embedded model query. Add your lookup type after the embedded +model field you're querying, prefixed by double underscores. + Example ``````` -This example uses a lookup that spans the ``Movie`` and ``Award`` -relationship. The ``Movie`` model's ``awards`` field has an -embedded ``Award`` model value. This embedded model represents -the ``awards`` object field in the ``sample_mflix.movies`` collection +This example uses a lookup to query the ``Award`` model, which is embedded +in the ``Movie`` model. This embedded model represents the +``awards`` field in the ``sample_mflix.movies`` collection and its nested ``wins``, ``nominations``, and ``text`` fields. The -following code uses a lookup to query for documents in which the ``awards.wins`` -nested field value is ``93``: +following code queries for documents in which the ``awards.wins`` +nested field value is greater than ``150``: .. io-code-block:: :copyable: @@ -640,17 +649,21 @@ nested field value is ``93``: .. output:: :visible: false - , ]> + , + , , + , , , + , , , + , ]> .. _django-query-arrayfield: Query an ArrayField -~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~ You can query data stored in an ``ArrayField`` value by using the standard query syntax. {+django-odm+} provides additional field lookup types for querying ``ArrayField`` values, -as described in the following table: +which are described in the following table: .. list-table:: :header-rows: 1 @@ -659,27 +672,27 @@ as described in the following table: * - Lookup Type - Description - * - ``__contains`` + * - ``contains`` - | Matches fields that store the provided value as a subset of their data. This ``ArrayField`` lookup overrides the - ``__contains`` lookup described in the :ref:`django-query-text-match` + ``contains`` lookup described in the :ref:`django-query-text-match` section of this guide. - * - ``__contained_by`` + * - ``contained_by`` - | Matches fields that store a subset of the provided values. - This lookup type is the inverse of ``__contains``. + This lookup type is the inverse of ``contains``. - * - ``__overlap`` + * - ``overlap`` - | Matches field that store any of the provided values. - * - ``__len`` + * - ``len`` - | Matches fields that store the number of values provided. Example ``````` -The following example uses the ``__overlap`` lookup to query -for documents whose ``genres`` field stores any values in the +The following example uses the ``overlap`` lookup to query +for documents whose ``genres`` field contains any values in the ``["Adventure", "Family"]`` array: .. io-code-block:: @@ -713,7 +726,7 @@ section. Chain each field and nested field name together, separated by double underscores (``__``), until you reach the field you want to query. -The following example queries the ``imdb`` field, a ``JSONField``, +The following example queries the ``JSONField``-valued ``imdb`` field for values of its nested ``votes`` field that exceed ``900000``: .. io-code-block:: @@ -811,7 +824,7 @@ for a document whose primary key is ``ObjectId("573a1394f29313caabce0d37")``: The ``Movie`` model, which represents the ``sample_mflix.movies`` collection, uses the ``id`` field as its primary key. The following example constructs -the same query as the preceding code: +the same query as the preceding code by using the ``id`` field: .. literalinclude:: /includes/interact-data/specify-a-query.py :language: python From e1e80ea2470ca3bbb70ef4c734048ff7ecad0b9f Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 17:32:40 -0500 Subject: [PATCH 16/23] fixes --- source/interact-data/specify-a-query.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 998c8b5..4f147d5 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -202,8 +202,8 @@ Exclude Matching Documents To query a collection for documents that do not meet your search criteria, call the ``exclude()`` method on your model's -``Manager`` class. Pass the exclusion criteria as an -argument to the ``exclude()`` method. +manager. Pass the exclusion criteria as an argument to the +``exclude()`` method. The following example calls the ``exclude()`` method to exclude documents released before January 1, 1980 from the results: @@ -551,7 +551,7 @@ Example This example performs the following actions: -- Calls the ``filter()`` method on the ``Movie`` model's ``Manager`` to query +- Calls the ``filter()`` method on the ``Movie`` model's manager to query the ``sample_mflix.movies`` collection - Queries documents that have a ``released`` value of ``datetime(2010, 7, 16)`` (July 16, 2010) From a28644b195861d91e7127231265e1d909acb4081 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 17:34:50 -0500 Subject: [PATCH 17/23] date --- source/interact-data/specify-a-query.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 4f147d5..3f1ed95 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -206,7 +206,8 @@ manager. Pass the exclusion criteria as an argument to the ``exclude()`` method. The following example calls the ``exclude()`` method to -exclude documents released before January 1, 1980 from the results: +exclude documents released before ``datetime(1980, 1, 1)`` (January 1, 1980) +from the results: .. io-code-block:: :copyable: From c8885518adabfd6719e7593bdd9f7bc305262c84 Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 17:40:53 -0500 Subject: [PATCH 18/23] fix --- source/includes/interact-data/specify-a-query.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index 45de121..531e574 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -54,7 +54,8 @@ def __str__(self): # start-filter-combine Movie.objects.filter( (Q(title__startswith="Funny") | Q(title__startswith="Laugh")) - & ~Q(genres__contains=["Comedy"])) + & ~Q(genres__contains=["Comedy"]) +) # end-filter-combine # start-sort From 1f08717daede9a6a6aae019b0812edc07b910a5e Mon Sep 17 00:00:00 2001 From: norareidy Date: Wed, 22 Jan 2025 18:32:15 -0500 Subject: [PATCH 19/23] use include --- snooty.toml | 1 + source/includes/use-sample-data.rst | 23 +++++++++++ source/interact-data/specify-a-query.txt | 49 ++++++++++-------------- 3 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 source/includes/use-sample-data.rst diff --git a/snooty.toml b/snooty.toml index 25222d6..fdf69ab 100644 --- a/snooty.toml +++ b/snooty.toml @@ -13,3 +13,4 @@ api = "https://django-mongodb.readthedocs.io/en/latest/" mdb-server = "MongoDB Server" django-version = "5.0" django-docs = "https://docs.djangoproject.com/en/{+django-version+}" +framework = "Django" diff --git a/source/includes/use-sample-data.rst b/source/includes/use-sample-data.rst new file mode 100644 index 0000000..37407be --- /dev/null +++ b/source/includes/use-sample-data.rst @@ -0,0 +1,23 @@ +The |model-classes| an inner ``Meta`` class and a ``__str__()`` method. +To learn about these model features, see :ref:`django-models-define` in the +Create Models guide. + +Run Code Examples +````````````````` + +You can use the Python interactive shell to run the code examples. +To enter the shell, run the following command from your project's +root directory: + +.. code-block:: bash + + python manage.py shell + +After entering the Python shell, ensure that you import the following models and +modules: + +|model-imports| + +To learn how to create a {+framework+} application that uses the ``Movie`` +model and the Python interactive shell to interact with MongoDB documents, +visit the :ref:`django-get-started` tutorial. \ No newline at end of file diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 3f1ed95..d3db250 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -33,22 +33,22 @@ complex matching criteria. Query API ~~~~~~~~~ -The Django ``QuerySet`` API provides methods that allow you to retrieve +The {+framework+} ``QuerySet`` API provides methods that allow you to retrieve model objects. To run a MongoDB database query, call ``QuerySet`` methods on your model's manager. The ``Manager`` class handles database operations and allows you to interact with your MongoDB data by referencing -Django models. By default, Django adds a ``Manager`` named ``objects`` +{+framework+} models. By default, {+framework+} adds a ``Manager`` named ``objects`` to every model class. When you assign a ``QuerySet`` to a variable, {+django-odm+} does not perform the operation until you evaluate the variable. After -evaluating the ``QuerySet``, Django saves the query results in the ``QuerySet`` +evaluating the ``QuerySet``, {+framework+} saves the query results in the ``QuerySet`` cache. Future evaluations of the ``QuerySet`` use the cached results. .. tip:: - To learn more about the Django ``QuerySet`` API, see `QuerySet API reference - <{+django-docs+}/ref/models/querysets/>`__ in the Django documentation. + To learn more about the {+framework+} ``QuerySet`` API, see `QuerySet API reference + <{+django-docs+}/ref/models/querysets/>`__ in the {+framework+} documentation. Sample Data ~~~~~~~~~~~ @@ -64,26 +64,19 @@ of its ``awards`` field. These model classes have the following definitions: :language: python :copyable: -You can use the Python interactive shell to run the code examples. -To enter the shell, run the following command from your project's -root directory: +.. include:: /includes/use-sample-data.rst -.. code-block:: bash + .. replacement:: model-classes - python manage.py shell + ``Movie`` model includes -After entering the Python shell, ensure that you import the following models and -modules: + .. replacement:: model-imports -.. code-block:: python - - from .models import Movie, Award - from django.utils import timezone - from datetime import datetime + .. code-block:: python -To learn how to create a Django application that uses the ``Movie`` -model and the Python interactive shell to interact with MongoDB documents, -visit the :ref:`django-get-started` tutorial. + from .models import Movie, Award + from django.utils import timezone + from datetime import datetime Run a Query ----------- @@ -243,7 +236,7 @@ from the results: Run Raw Database Queries ~~~~~~~~~~~~~~~~~~~~~~~~ -If you want to run complex queries that Django's query API +If you want to run complex queries that {+framework+}'s query API does not support, you can use the ``raw_aggregate()`` method. This method allows you to specify your query criteria in a MongoDB aggregation pipeline, which you pass as an argument to @@ -275,7 +268,7 @@ expression matching, and year value matching for datetime fields. To view a full list of lookup types, see `Field lookups <{+django-docs+}/ref/models/querysets/#field-lookups>`__ in the - ``QuerySet`` Django API reference. + ``QuerySet`` {+framework+} API reference. This section describes how to refine your query filters in the following ways: @@ -424,15 +417,15 @@ in the following ways: - Pass multiple query filters to your query method, separated by commas. To view an example, see `Retrieving objects <{+django-docs+}/topics/db/queries/#retrieving-objects>`__ in the - Django documentation. + {+framework+} documentation. - Chain query methods together. To learn more, see `Chaining filters - <{+django-docs+}/topics/db/queries/#chaining-filters>`__ in the Django + <{+django-docs+}/topics/db/queries/#chaining-filters>`__ in the {+framework+} documentation. - Use ``Q`` objects and separate each object with a logical operator. To learn more, see `Complex lookups with Q objects - <{+django-docs+}/topics/db/queries/#complex-lookups-with-q-objects>`__ in the Django + <{+django-docs+}/topics/db/queries/#complex-lookups-with-q-objects>`__ in the {+framework+} documentation. Q Object Example @@ -766,7 +759,7 @@ provided ``KT()`` expressions. .. tip:: To learn more about ``KT()`` expressions and the ``annotate()`` method, - see the following resources in the Django documentation: + see the following resources in the {+framework+} documentation: - `KT() expressions <{+django-docs+}/topics/db/queries/#module-django.db.models.fields.json>`__ - `annotate() <{+django-docs+}/ref/models/querysets/#django.db.models.query.QuerySet.annotate>`__ @@ -842,5 +835,5 @@ pipeline syntax, see the :ref:`django-raw-queries` guide. To learn how to perform other ``QuerySet`` operations, see the :ref:`django-crud` guide. -To learn more about Django queries, see `Making queries <{+django-docs+}/topics/db/queries>`__ -in the Django documentation. +To learn more about {+framework+} queries, see `Making queries <{+django-docs+}/topics/db/queries>`__ +in the {+framework+} documentation. From 8967686be7405889611882ab384eb1f313a765ee Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 23 Jan 2025 14:42:11 -0500 Subject: [PATCH 20/23] RR feedback 2 --- source/includes/use-sample-data.rst | 6 ++++-- source/interact-data/specify-a-query.txt | 21 --------------------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/source/includes/use-sample-data.rst b/source/includes/use-sample-data.rst index 37407be..15433ac 100644 --- a/source/includes/use-sample-data.rst +++ b/source/includes/use-sample-data.rst @@ -1,5 +1,7 @@ -The |model-classes| an inner ``Meta`` class and a ``__str__()`` method. -To learn about these model features, see :ref:`django-models-define` in the +The |model-classes| an inner ``Meta`` class, which specifies +model metadata, and a ``__str__()`` method, which sets the +model's string representation to its ``title`` field. To learn about +these model features, see :ref:`django-models-define` in the Create Models guide. Run Code Examples diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index d3db250..25c5e53 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -121,10 +121,6 @@ all documents in the ``sample_mflix.movies`` collection: , , , , , , , - , , - , , , - , , , - , , '...(remaining elements truncated)...']> .. _django-query-retrieve-matching: @@ -217,11 +213,6 @@ from the results: , , , , , , , - , , - , , - , , - , , - , , , '...(remaining elements truncated)...']> .. tip:: @@ -338,10 +329,6 @@ includes the text ``"coming-of-age"``: , , , , , , , , , - , - , , - , , , - , , , '...(remaining elements truncated)...']> .. _django-query-comparison: @@ -399,11 +386,6 @@ is less than or equal to ``50``: , , , , , , - , , , - , , - , , , - , , - , , '...(remaining elements truncated)...']> .. _django-query-combine: @@ -704,9 +686,6 @@ for documents whose ``genres`` field contains any values in the , , , , , , , , , - , , , - , , , - , , , '...(remaining elements truncated)...']> .. _django-query-jsonfield: From 877335f8c1501d90e99c2afea747a02a37aea284 Mon Sep 17 00:00:00 2001 From: norareidy Date: Thu, 23 Jan 2025 14:42:56 -0500 Subject: [PATCH 21/23] embeddedmodel --- source/includes/interact-data/specify-a-query.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/includes/interact-data/specify-a-query.py b/source/includes/interact-data/specify-a-query.py index 531e574..4f2e0ed 100644 --- a/source/includes/interact-data/specify-a-query.py +++ b/source/includes/interact-data/specify-a-query.py @@ -1,8 +1,9 @@ # start-models from django.db import models +from django_mongodb_backend.models import EmbeddedModel from django_mongodb_backend.fields import EmbeddedModelField, ArrayField -class Award(models.Model): +class Award(EmbeddedModel): wins = models.IntegerField(default=0) nominations = models.IntegerField(default=0) text = models.CharField(max_length=100) From 8ac2b61fb33e97b2285f8f69b7ebb6019270a57c Mon Sep 17 00:00:00 2001 From: norareidy Date: Fri, 24 Jan 2025 13:50:48 -0500 Subject: [PATCH 22/23] test link --- source/interact-data/specify-a-query.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index 25c5e53..f00320f 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -49,6 +49,7 @@ cache. Future evaluations of the ``QuerySet`` use the cached results. To learn more about the {+framework+} ``QuerySet`` API, see `QuerySet API reference <{+django-docs+}/ref/models/querysets/>`__ in the {+framework+} documentation. + :py:class:`~django.db.models.QuerySet` Sample Data ~~~~~~~~~~~ From 67790cf0780b8e6a1f119b52a7e8aa91d2360603 Mon Sep 17 00:00:00 2001 From: norareidy Date: Fri, 24 Jan 2025 13:57:12 -0500 Subject: [PATCH 23/23] try again --- source/interact-data/specify-a-query.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/interact-data/specify-a-query.txt b/source/interact-data/specify-a-query.txt index f00320f..1905633 100644 --- a/source/interact-data/specify-a-query.txt +++ b/source/interact-data/specify-a-query.txt @@ -49,7 +49,7 @@ cache. Future evaluations of the ``QuerySet`` use the cached results. To learn more about the {+framework+} ``QuerySet`` API, see `QuerySet API reference <{+django-docs+}/ref/models/querysets/>`__ in the {+framework+} documentation. - :py:class:`~django.db.models.QuerySet` + :py:class:`~django.db.models.query.QuerySet` Sample Data ~~~~~~~~~~~