diff options
| author | Marc Tamlyn <marc.tamlyn@gmail.com> | 2014-03-14 17:34:49 +0000 |
|---|---|---|
| committer | Marc Tamlyn <marc.tamlyn@gmail.com> | 2014-11-04 09:26:40 +0000 |
| commit | 36f514f06553ef299001b4e9a5f63ec806a50581 (patch) | |
| tree | 966c1b958c49cd266f76c385acb0a2bd330f7c10 /docs/ref | |
| parent | 5c517ec21839358249c6f17611abbf84661fb200 (diff) | |
Added HStoreField.
Thanks to `django-hstore` for inspiration in some areas, and many people
for reviews.
Diffstat (limited to 'docs/ref')
| -rw-r--r-- | docs/ref/contrib/postgres/fields.txt | 166 | ||||
| -rw-r--r-- | docs/ref/contrib/postgres/forms.txt | 20 | ||||
| -rw-r--r-- | docs/ref/contrib/postgres/index.txt | 2 | ||||
| -rw-r--r-- | docs/ref/contrib/postgres/operations.txt | 27 | ||||
| -rw-r--r-- | docs/ref/contrib/postgres/validators.txt | 20 |
5 files changed, 233 insertions, 2 deletions
diff --git a/docs/ref/contrib/postgres/fields.txt b/docs/ref/contrib/postgres/fields.txt index 49ce5368c8..3fba239e74 100644 --- a/docs/ref/contrib/postgres/fields.txt +++ b/docs/ref/contrib/postgres/fields.txt @@ -61,8 +61,8 @@ ArrayField When nesting ``ArrayField``, whether you use the `size` parameter or not, PostgreSQL requires that the arrays are rectangular:: - from django.db import models from django.contrib.postgres.fields import ArrayField + from django.db import models class Board(models.Model): pieces = ArrayField(ArrayField(models.IntegerField())) @@ -95,7 +95,7 @@ We will use the following example model:: name = models.CharField(max_length=200) tags = ArrayField(models.CharField(max_length=200), blank=True) - def __str__(self): # __unicode__ on python 2 + def __str__(self): # __unicode__ on Python 2 return self.name .. fieldlookup:: arrayfield.contains @@ -240,3 +240,165 @@ At present using :attr:`~django.db.models.Field.db_index` will create a ``btree`` index. This does not offer particularly significant help to querying. A more useful index is a ``GIN`` index, which you should create using a :class:`~django.db.migrations.operations.RunSQL` operation. + +HStoreField +----------- + +.. class:: HStoreField(**options) + + A field for storing mappings of strings to strings. The Python data type + used is a ``dict``. + +.. note:: + + On occasions it may be useful to require or restrict the keys which are + valid for a given field. This can be done using the + :class:`~django.contrib.postgres.validators.KeysValidator`. + +Querying HStoreField +^^^^^^^^^^^^^^^^^^^^ + +In addition to the ability to query by key, there are a number of custom +lookups available for ``HStoreField``. + +We will use the following example model:: + + from django.contrib.postgres.fields import HStoreField + from django.db import models + + class Dog(models.Model): + name = models.CharField(max_length=200) + data = HStoreField() + + def __str__(self): # __unicode__ on Python 2 + return self.name + +.. fieldlookup:: hstorefield.key + +Key lookups +~~~~~~~~~~~ + +To query based on a given key, you simply use that key as the lookup name:: + + >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'}) + >>> Dog.objects.create(name='Meg', data={'breed': 'collie'}) + + >>> Dog.objects.filter(data__breed='collie') + [<Dog: Meg>] + +You can chain other lookups after key lookups:: + + >>> Dog.objects.filter(data__breed__contains='l') + [<Dog: Rufus>, Dog: Meg>] + +If the key you wish to query by clashes with the name of another lookup, you +need to use the :lookup:`hstorefield.contains` lookup instead. + +.. warning:: + + Since any string could be a key in a hstore value, any lookup other than + those listed below will be interpreted as a key lookup. No errors are + raised. Be extra careful for typing mistakes, and always check your queries + work as you intend. + +.. fieldlookup:: hstorefield.contains + +contains +~~~~~~~~ + +The :lookup:`contains` lookup is overridden on +:class:`~django.contrib.postgres.fields.HStoreField`. The returned objects are +those where the given ``dict`` of key-value pairs are all contained in the +field. It uses the SQL operator ``@>``. For example:: + + >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'}) + >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'}) + >>> Dog.objects.create(name='Fred', data={}) + + >>> Dog.objects.filter(data__contains={'owner': 'Bob'}) + [<Dog: Rufus>, <Dog: Meg>] + + >>> Dog.objects.filter(data__contains={'breed': 'collie'}) + [<Dog: Meg>] + +.. fieldlookup:: hstorefield.contained_by + +contained_by +~~~~~~~~~~~~ + +This is the inverse of the :lookup:`contains <hstorefield.contains>` lookup - +the objects returned will be those where the key-value pairs on the object are +a subset of those in the value passed. It uses the SQL operator ``<@``. For +example:: + + >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'}) + >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'}) + >>> Dog.objects.create(name='Fred', data={}) + + >>> Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'}) + [<Dog: Meg>, <Dog: Fred>] + + >>> Dog.objects.filter(data__contained_by={'breed': 'collie'}) + [<Dog: Fred>] + +.. fieldlookup:: hstorefield.has_key + +has_key +~~~~~~~ + +Returns objects where the given key is in the data. Uses the SQL operator +``?``. For example:: + + >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'}) + >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'}) + + >>> Dog.objects.filter(data__has_key='owner') + [<Dog: Meg>] + +.. fieldlookup:: hstorefield.has_keys + +has_keys +~~~~~~~~ + +Returns objects where all of the given keys are in the data. Uses the SQL operator +``?&``. For example:: + + >>> Dog.objects.create(name='Rufus', data={}) + >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'}) + + >>> Dog.objects.filter(data__has_keys=['breed', 'owner']) + [<Dog: Meg>] + +.. fieldlookup:: hstorefield.keys + +keys +~~~~ + +Returns objects where the array of keys is the given value. Note that the order +is not guaranteed to be reliable, so this transform is mainly useful for using +in conjunction with lookups on +:class:`~django.contrib.postgres.fields.ArrayField`. Uses the SQL function +``akeys()``. For example:: + + >>> Dog.objects.create(name='Rufus', data={'toy': 'bone'}) + >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'}) + + >>> Dog.objects.filter(data__keys__overlap=['breed', 'toy']) + [<Dog: Rufus>, <Dog: Meg>] + +.. fieldlookup:: hstorefield.values + +values +~~~~~~ + +Returns objects where the array of values is the given value. Note that the +order is not guaranteed to be reliable, so this transform is mainly useful for +using in conjunction with lookups on +:class:`~django.contrib.postgres.fields.ArrayField`. Uses the SQL function +``avalues()``. For example:: + + >>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'}) + >>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'}) + + >>> Dog.objects.filter(data__values__contains=['collie']) + [<Dog: Meg>] diff --git a/docs/ref/contrib/postgres/forms.txt b/docs/ref/contrib/postgres/forms.txt index 6cad537f3b..261cc7f4f4 100644 --- a/docs/ref/contrib/postgres/forms.txt +++ b/docs/ref/contrib/postgres/forms.txt @@ -133,3 +133,23 @@ SplitArrayField ['1', '2', ''] # -> [1, 2] ['1', '', '3'] # -> [1, None, 3] ['', '2', ''] # -> [None, 2] + +HStoreField +----------- + +.. class:: HStoreField + + A field which accepts JSON encoded data for an + :class:`~django.contrib.postgres.fields.HStoreField`. It will cast all the + values to strings. It is represented by an HTML ``<textarea>``. + + .. admonition:: User friendly forms + + ``HStoreField`` is not particularly user friendly in most cases, + however it is a useful way to format data from a client-side widget for + submission to the server. + + .. note:: + On occasions it may be useful to require or restrict the keys which are + valid for a given field. This can be done using the + :class:`~django.contrib.postgres.validators.KeysValidator`. diff --git a/docs/ref/contrib/postgres/index.txt b/docs/ref/contrib/postgres/index.txt index 31969222ca..b23db125f2 100644 --- a/docs/ref/contrib/postgres/index.txt +++ b/docs/ref/contrib/postgres/index.txt @@ -26,3 +26,5 @@ a number of PostgreSQL specific data types. fields forms + operations + validators diff --git a/docs/ref/contrib/postgres/operations.txt b/docs/ref/contrib/postgres/operations.txt new file mode 100644 index 0000000000..4b9b7f5c44 --- /dev/null +++ b/docs/ref/contrib/postgres/operations.txt @@ -0,0 +1,27 @@ +Database migration operations +============================= + +All of these :doc:`operations </ref/migration-operations>` are available from +the ``django.contrib.postgres.operations`` module. + +.. currentmodule:: django.contrib.postgres.operations + +CreateExtension +--------------- + +.. class:: CreateExtension(name) + + An ``Operation`` subclass which installs PostgreSQL extensions. + + .. attribute:: name + + This is a required argument. The name of the extension to be installed. + +HStoreExtension +--------------- + +.. class:: HStoreExtension() + + A subclass of :class:`~django.contrib.postgres.operations.CreateExtension` + which will install the ``hstore`` extension and also immediately set up the + connection to interpret hstore data. diff --git a/docs/ref/contrib/postgres/validators.txt b/docs/ref/contrib/postgres/validators.txt new file mode 100644 index 0000000000..76cd52510a --- /dev/null +++ b/docs/ref/contrib/postgres/validators.txt @@ -0,0 +1,20 @@ +========== +Validators +========== + +.. module:: django.contrib.postgres.validators + +``KeysValidator`` +----------------- + +.. class:: KeysValidator(keys, strict=False, messages=None) + + Validates that the given keys are contained in the value. If ``strict`` is + ``True``, then it also checks that there are no other keys present. + + The ``messages`` passed should be a dict containing the keys + ``missing_keys`` and/or ``extra_keys``. + + .. note:: + Note that this checks only for the existence of a given key, not that + the value of a key is non-empty. |
