Skip to content

Commit 6470f02

Browse files
committed
Update docs
1 parent 811defa commit 6470f02

File tree

6 files changed

+97
-40
lines changed

6 files changed

+97
-40
lines changed

docs/howto/queryable-encryption.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ encrypted database in your :setting:`django:DATABASES` setting.
4141

4242
This database will be used to store encrypted fields in your models. The
4343
following example shows how to configure an encrypted database using the
44-
:class:`pymongo.encryption_options.AutoEncryptionOpts` from the
45-
:mod:`pymongo.encryption_options` module.
44+
:class:`AutoEncryptionOpts <pymongo.encryption_options.AutoEncryptionOpts>` from the
45+
:mod:`encryption_options <pymongo.encryption_options>` module.
4646

4747
This example uses a local KMS provider and a key vault namespace for storing
4848
encryption keys.
@@ -188,6 +188,7 @@ Example of KMS configuration with AWS KMS:
188188
def kms_provider(self, model, **hints):
189189
return "aws"
190190
191+
.. _qe-configuring-encrypted-fields-map:
191192

192193
Configuring the ``encrypted_fields_map``
193194
========================================

docs/ref/django-admin.rst

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,35 @@ Available commands
2222
.. django-admin:: showencryptedfieldsmap
2323

2424
This command shows the mapping of encrypted fields to attributes including
25-
data type, data keys and query types. It can be used to set the
26-
``encrypted_fields_map`` in ``AutoEncryptionOpts``.
25+
data type, data keys and query types. Its output can be used to set the
26+
:ref:`encrypted_fields_map <qe-configuring-encrypted-fields-map>` argument
27+
in :class:`AutoEncryptionOpts
28+
<pymongo.encryption_options.AutoEncryptionOpts>`.
2729

2830
.. django-admin-option:: --database DATABASE
2931

3032
Specifies the database to use. Defaults to ``default``.
33+
34+
To show the encrypted fields map for a database named ``encrypted``, run:
35+
36+
.. code-block:: console
37+
38+
$ python manage.py showencryptedfieldsmap --database encrypted
39+
40+
The output will look like::
41+
42+
{
43+
"myapp.mymodel": {
44+
"encrypted_field_1": {
45+
"bsonType": "string",
46+
"keyId": "UUID('...')",
47+
"queries": ["equality", "range"]
48+
},
49+
"encrypted_field_2": {
50+
"bsonType": "int",
51+
"keyId": "UUID('...')",
52+
"queries": ["equality"]
53+
}
54+
},
55+
...
56+
}

docs/ref/models/encrypted-fields.rst

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,29 +88,32 @@ Queryable Encryption.
8888

8989
.. versionadded:: 5.2.3
9090

91-
A mixin that can be used to create custom encrypted fields that support
92-
MongoDB's Queryable Encryption.
91+
A mixin that can be used to create custom encrypted fields with Queryable
92+
Encryption.
9393

94-
To create a custom encrypted field, inherit from ``EncryptedFieldMixin`` and
95-
the desired Django field class.
96-
97-
98-
For example, to create a custom encrypted field that supports ``equality``
99-
queries, you can define it as follows:
94+
To create an encrypted field, inherit from ``EncryptedFieldMixin`` and
95+
your custom field class:
10096

10197
.. code-block:: python
10298
10399
from django.db import models
104100
from django_mongodb_backend.fields import EncryptedFieldMixin
105-
from .models import MyField
101+
from myapp.fields import MyField
106102
107103
108104
class MyEncryptedField(EncryptedFieldMixin, MyField):
109105
pass
110106
111107
108+
You can then use your custom encrypted field in a model, specifying the
109+
desired query types:
110+
111+
.. code-block:: python
112+
112113
class MyModel(models.Model):
113114
my_encrypted_field = MyEncryptedField(
114115
queries={"queryType": "equality"},
115-
# Other field options...
116+
)
117+
my_encrypted_field_too = MyEncryptedField(
118+
queries={"queryType": "range"},
116119
)

docs/ref/utils.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,41 @@ following parts can be considered stable.
4848

4949
But for maximum flexibility, construct :setting:`DATABASES` manually as
5050
described in :ref:`configuring-databases-setting`.
51+
52+
.. versionadded:: 5.2.3
53+
54+
``model_has_encrypted_fields()``
55+
=================================
56+
57+
.. function:: model_has_encrypted_fields(model)
58+
59+
Returns ``True`` if the given Django model has any fields that use
60+
encrypted models.
61+
62+
Example usage in a database router::
63+
64+
from django_mongodb_backend.utils import model_has_encrypted_fields
65+
66+
class EncryptedRouter:
67+
def db_for_read(self, model, **hints):
68+
if model_has_encrypted_fields(model):
69+
return "encrypted"
70+
return "default"
71+
72+
def db_for_write(self, model, **hints):
73+
if model_has_encrypted_fields(model):
74+
return "encrypted"
75+
return "default"
76+
77+
def allow_migrate(self, db, app_label, model_name=None, **hints):
78+
if hints.get("model"):
79+
if model_has_encrypted_fields(hints["model"]):
80+
return db == "encrypted"
81+
else:
82+
return db == "default"
83+
return None
84+
85+
def kms_provider(self, model):
86+
if model_has_encrypted_fields(model):
87+
return "local"
88+
return None

docs/topics/known-issues.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Model fields
2626
- :class:`~django.db.models.CompositePrimaryKey`
2727
- :class:`~django.db.models.GeneratedField`
2828

29+
.. _known-issues-limitations-querying:
30+
2931
Querying
3032
========
3133

docs/topics/queryable-encryption.rst

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ queries on certain encrypted fields. To use encrypted fields in your models,
2121
import the necessary field types from ``django_mongodb_backend.models`` and
2222
define your models as usual.
2323

24+
Here's the `Python Queryable Encryption Tutorial`_ example implemented in
25+
Django:
26+
2427
.. code-block:: python
2528
2629
# myapp/models.py
@@ -94,8 +97,10 @@ query type in the model field definition. For example, if you want to query the
9497
billing = EncryptedEmbeddedModelField("Billing")
9598
bill_amount = models.DecimalField(max_digits=10, decimal_places=2)
9699
97-
Query types
98-
~~~~~~~~~~~
100+
.. _qe-available-query-types:
101+
102+
Available query types
103+
~~~~~~~~~~~~~~~~~~~~~
99104

100105
The ``queries`` option should be a dictionary that specifies the type of queries
101106
that can be performed on the field. The :ref:`available query types
@@ -116,30 +121,12 @@ For example, to find a patient by their SSN, you can do the following::
116121
>>> patient.name
117122
'Bob'
118123

119-
120124
QuerySet limitations
121125
~~~~~~~~~~~~~~~~~~~~
122126

123-
When using Django QuerySets with MongoDB Queryable Encryption, it’s important to
124-
understand that many typical ORM features are restricted because the database
125-
only sees encrypted ciphertext, not plaintext. This means that only certain
126-
query types are supported, and a lot of filtering, sorting, and aggregating must
127-
be done client-side after decryption. Key limitations include:
128-
129-
- **Equality only filtering** – You can filter encrypted fields using exact
130-
matches, but operators like contains, startswith, regex, or unsupported range
131-
lookups will not work.
132-
- **No server-side sorting** – .order_by() on encrypted fields won’t produce
133-
meaningful results; sorting needs to happen after decryption in Python.
134-
- **No server-side aggregation** – Functions like annotate() or aggregate()
135-
won’t operate on encrypted fields; you must aggregate locally after fetching
136-
data.
137-
- **Index constraints** – Queries are only possible on encrypted fields that
138-
have a configured queryable encryption index and keys available on the client.
139-
- **No joins on encrypted fields** – Filtering across relationships using
140-
encrypted foreign keys is unsupported because matching must happen
141-
client-side.
142-
143-
In short, when working with Queryable Encryption, design your queries to use
144-
exact matches only on encrypted fields, and plan to handle any sorting or
145-
aggregation after results are decrypted in your application code.
127+
In addition to :ref:`Django MongoDB Backend's QuerySet limitations
128+
<known-issues-limitations-querying>`,
129+
130+
.. TODO
131+
132+
.. _Python Queryable Encryption Tutorial: https://github.com/mongodb/docs/tree/main/content/manual/manual/source/includes/qe-tutorials/python

0 commit comments

Comments
 (0)