@@ -5,6 +5,172 @@ Model field reference
55
66Some MongoDB-specific fields are available in ``django_mongodb.fields ``.
77
8+ ``ArrayField ``
9+ --------------
10+
11+ .. class :: ArrayField(base_field, size=None, **options)
12+
13+ A field for storing lists of data. Most field types can be used, and you
14+ pass another field instance as the :attr: `base_field
15+ <ArrayField.base_field> `. You may also specify a :attr: `size
16+ <ArrayField.size> `. ``ArrayField `` can be nested to store multi-dimensional
17+ arrays.
18+
19+ If you give the field a :attr: `~django.db.models.Field.default `, ensure
20+ it's a callable such as ``list `` (for an empty default) or a callable that
21+ returns a list (such as a function). Incorrectly using ``default=[] ``
22+ creates a mutable default that is shared between all instances of
23+ ``ArrayField ``.
24+
25+ .. attribute :: base_field
26+
27+ This is a required argument.
28+
29+ Specifies the underlying data type and behavior for the array. It
30+ should be an instance of a subclass of
31+ :class: `~django.db.models.Field `. For example, it could be an
32+ :class: `~django.db.models.IntegerField ` or a
33+ :class: `~django.db.models.CharField `. Most field types are permitted,
34+ with the exception of those handling relational data
35+ (:class: `~django.db.models.ForeignKey `,
36+ :class: `~django.db.models.OneToOneField ` and
37+ :class: `~django.db.models.ManyToManyField `) and file fields (
38+ :class: `~django.db.models.FileField ` and
39+ :class: `~django.db.models.ImageField `).
40+
41+ It is possible to nest array fields - you can specify an instance of
42+ ``ArrayField `` as the ``base_field ``. For example::
43+
44+ from django.db import models
45+ from django_mongodb.fields import ArrayField
46+
47+
48+ class ChessBoard(models.Model):
49+ board = ArrayField(
50+ ArrayField(
51+ models.CharField(max_length=10, blank=True),
52+ size=8,
53+ ),
54+ size=8,
55+ )
56+
57+ Transformation of values between the database and the model, validation
58+ of data and configuration, and serialization are all delegated to the
59+ underlying base field.
60+
61+ .. attribute :: size
62+
63+ This is an optional argument.
64+
65+ If passed, the array will have a maximum size as specified, validated
66+ only by forms.
67+
68+ Querying ``ArrayField ``
69+ ~~~~~~~~~~~~~~~~~~~~~~~
70+
71+ There are a number of custom lookups and transforms for :class: `ArrayField `.
72+ We will use the following example model::
73+
74+ from django.db import models
75+ from django_mongodb.fields import ArrayField
76+
77+
78+ class Post(models.Model):
79+ name = models.CharField(max_length=200)
80+ tags = ArrayField(models.CharField(max_length=200), blank=True)
81+
82+ def __str__(self):
83+ return self.name
84+
85+ .. fieldlookup :: arrayfield.contains
86+
87+ ``contains ``
88+ ^^^^^^^^^^^^
89+
90+ The :lookup: `contains ` lookup is overridden on :class: `ArrayField `. The
91+ returned objects will be those where the values passed are a subset of the
92+ data. It uses the ``$setIntersection `` operator. For example:
93+
94+ .. code-block :: pycon
95+
96+ >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
97+ >>> Post.objects.create(name="Second post", tags=["thoughts"])
98+ >>> Post.objects.create(name="Third post", tags=["tutorial", "django"])
99+
100+ >>> Post.objects.filter(tags__contains=["thoughts"])
101+ <QuerySet [<Post: First post>, <Post: Second post>]>
102+
103+ >>> Post.objects.filter(tags__contains=["django"])
104+ <QuerySet [<Post: First post>, <Post: Third post>]>
105+
106+ >>> Post.objects.filter(tags__contains=["django", "thoughts"])
107+ <QuerySet [<Post: First post>]>
108+
109+ .. fieldlookup :: arrayfield.len
110+
111+ ``len ``
112+ ^^^^^^^
113+
114+ Returns the length of the array. The lookups available afterward are those
115+ available for :class: `~django.db.models.IntegerField `. For example:
116+
117+ .. code-block :: pycon
118+
119+ >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
120+ >>> Post.objects.create(name="Second post", tags=["thoughts"])
121+
122+ >>> Post.objects.filter(tags__len=1)
123+ <QuerySet [<Post: Second post>]>
124+
125+ .. fieldlookup :: arrayfield.index
126+
127+ Index transforms
128+ ^^^^^^^^^^^^^^^^
129+
130+ Index transforms index into the array. Any non-negative integer can be used.
131+ There are no errors if it exceeds the :attr: `size <ArrayField.size> ` of the
132+ array. The lookups available after the transform are those from the
133+ :attr: `base_field <ArrayField.base_field> `. For example:
134+
135+ .. code-block :: pycon
136+
137+ >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
138+ >>> Post.objects.create(name="Second post", tags=["thoughts"])
139+
140+ >>> Post.objects.filter(tags__0="thoughts")
141+ <QuerySet [<Post: First post>, <Post: Second post>]>
142+
143+ >>> Post.objects.filter(tags__1__iexact="Django")
144+ <QuerySet [<Post: First post>]>
145+
146+ >>> Post.objects.filter(tags__276="javascript")
147+ <QuerySet []>
148+
149+ These indexes use 0-based indexing.
150+
151+ .. fieldlookup :: arrayfield.slice
152+
153+ Slice transforms
154+ ^^^^^^^^^^^^^^^^
155+
156+ Slice transforms take a slice of the array. Any two non-negative integers can
157+ be used, separated by a single underscore. The lookups available after the
158+ transform do not change. For example:
159+
160+ .. code-block :: pycon
161+
162+ >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
163+ >>> Post.objects.create(name="Second post", tags=["thoughts"])
164+ >>> Post.objects.create(name="Third post", tags=["django", "python", "thoughts"])
165+
166+ >>> Post.objects.filter(tags__0_1=["thoughts"])
167+ <QuerySet [<Post: First post>, <Post: Second post>]>
168+
169+ >>> Post.objects.filter(tags__0_2__contains=["thoughts"])
170+ <QuerySet [<Post: First post>, <Post: Second post>]>
171+
172+ These indexes use 0-based indexing.
173+
8174``ObjectIdField ``
9175-----------------
10176
0 commit comments