8
unique_together
does not automatically add indexes for each field included in the list.
The new versions of Django suggest using Index & constraint meta options instead:
https://docs.djangoproject.com/en/3.2/ref/models/options/#unique-together
https://docs.djangoproject.com/en/3.2/ref/models/options/#index-together
https://docs.djangoproject.com/en/dev/ref/models/indexes/
And an example model from an open source project:
class GroupResult(models.Model):
"""Task Group result/status."""
group_id = models.CharField(
max_length=getattr(
settings,
"DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH",
255
),
unique=True,
verbose_name=_("Group ID"),
help_text=_("Celery ID for the Group that was run"),
)
date_created = models.DateTimeField(
auto_now_add=True,
verbose_name=_("Created DateTime"),
help_text=_("Datetime field when the group result was created in UTC"),
)
date_done = models.DateTimeField(
auto_now=True,
verbose_name=_("Completed DateTime"),
help_text=_("Datetime field when the group was completed in UTC"),
)
content_type = models.CharField(
max_length=128,
verbose_name=_("Result Content Type"),
help_text=_("Content type of the result data"),
)
content_encoding = models.CharField(
max_length=64,
verbose_name=_("Result Encoding"),
help_text=_("The encoding used to save the task result data"),
)
result = models.TextField(
null=True, default=None, editable=False,
verbose_name=_('Result Data'),
help_text=_('The data returned by the task. '
'Use content_encoding and content_type fields to read.'))
def as_dict(self):
return {
'group_id': self.group_id,
'result': self.result,
'date_done': self.date_done,
}
def __str__(self):
return f'<Group: {self.group_id}>'
objects = managers.GroupResultManager()
class Meta:
"""Table information."""
ordering = ['-date_done']
verbose_name = _('group result')
verbose_name_plural = _('group results')
indexes = [
models.Index(fields=['date_created']),
models.Index(fields=['date_done']),
]
38
For anyone coming here wondering if they need an index_together
in addition to unique_together
to get the indexβs performance benefit, the answer for Postgres is no, they are functionally the same.
- [Django]-Django error message "Add a related_name argument to the definition"
- [Django]-How do I create a slug in Django?
- [Django]-Django Admin Show Image from Imagefield
14
If unique_together
does add an index, it will be a multiple column index.
If you want one of the columns to be indexed individually, I believe you need to specify db_index=True
in the field definition.
- [Django]-Is there an easy way to populate SlugField from CharField?
- [Django]-Include intermediary (through model) in responses in Django Rest Framework
- [Django]-Django-Rest-Framework 3.0 Field name '<field>' is not valid for model `ModelBase`
7
In Django 1.5 and higher, you can use the {Model}.Meta.index_together
class attribute. If you had two fields named foo
and bar
, you would add:
class Meta(object):
index_together = unique_together = [
['foo', 'bar']
]
If you have only one set of unique fields, you can use a one-dimensional iterable for unique_together
. However, the documentation does not indicate that the same applies to index_together
.
This would also be okay:
class Meta(object):
unique_together = 'foo', 'bar'
index_together = [
['foo', 'bar']
]
This, however, is NOT supported by the documentation:
class Meta(object):
unique_together = 'foo', 'bar'
index_together = 'foo', 'bar'
- [Django]-Any way to make {% extends 'β¦' %} conditional? β Django
- [Django]-Python Django Global Variables
- [Django]-Django β Circular model import issue
1
According to the docs, it will only enforce uniqueness on database level. I think generally making a field unique does not imply it has an index. Though you could also simply check on db level if the index exists. Everything indicates though it does not.
- [Django]-Django β installing mysqlclient error: mysqlclient 1.3.13 or newer is required; you have 0.9.3
- [Django]-Error trying to install Postgres for python (psycopg2)
- [Django]-How to filter model results for multiple values for a many to many field in django