Return a list of distinct values for a given field. :param field: the field to select distinct values from .. note:: This is a command and won't take ordering or limit into account.
(self, field)
| 978 | return queryset |
| 979 | |
| 980 | def distinct(self, field): |
| 981 | """Return a list of distinct values for a given field. |
| 982 | |
| 983 | :param field: the field to select distinct values from |
| 984 | |
| 985 | .. note:: This is a command and won't take ordering or limit into |
| 986 | account. |
| 987 | """ |
| 988 | queryset = self.clone() |
| 989 | |
| 990 | try: |
| 991 | field = self._fields_to_dbfields([field]).pop() |
| 992 | except LookUpError: |
| 993 | pass |
| 994 | |
| 995 | raw_values = queryset._cursor.distinct(field) |
| 996 | if not self._auto_dereference: |
| 997 | return raw_values |
| 998 | |
| 999 | distinct = self._dereference(raw_values, 1, name=field, instance=self._document) |
| 1000 | |
| 1001 | doc_field = self._document._fields.get(field.split(".", 1)[0]) |
| 1002 | instance = None |
| 1003 | |
| 1004 | # We may need to cast to the correct type eg. ListField(EmbeddedDocumentField) |
| 1005 | EmbeddedDocumentField = _import_class("EmbeddedDocumentField") |
| 1006 | ListField = _import_class("ListField") |
| 1007 | GenericEmbeddedDocumentField = _import_class("GenericEmbeddedDocumentField") |
| 1008 | if isinstance(doc_field, ListField): |
| 1009 | doc_field = getattr(doc_field, "field", doc_field) |
| 1010 | if isinstance(doc_field, (EmbeddedDocumentField, GenericEmbeddedDocumentField)): |
| 1011 | instance = getattr(doc_field, "document_type", None) |
| 1012 | |
| 1013 | # handle distinct on subdocuments |
| 1014 | if "." in field: |
| 1015 | for field_part in field.split(".")[1:]: |
| 1016 | # if looping on embedded document, get the document type instance |
| 1017 | if instance and isinstance( |
| 1018 | doc_field, (EmbeddedDocumentField, GenericEmbeddedDocumentField) |
| 1019 | ): |
| 1020 | doc_field = instance |
| 1021 | # now get the subdocument |
| 1022 | doc_field = getattr(doc_field, field_part, doc_field) |
| 1023 | # We may need to cast to the correct type eg. ListField(EmbeddedDocumentField) |
| 1024 | if isinstance(doc_field, ListField): |
| 1025 | doc_field = getattr(doc_field, "field", doc_field) |
| 1026 | if isinstance( |
| 1027 | doc_field, (EmbeddedDocumentField, GenericEmbeddedDocumentField) |
| 1028 | ): |
| 1029 | instance = getattr(doc_field, "document_type", None) |
| 1030 | |
| 1031 | if instance and isinstance( |
| 1032 | doc_field, (EmbeddedDocumentField, GenericEmbeddedDocumentField) |
| 1033 | ): |
| 1034 | distinct = [instance(**doc) for doc in distinct] |
| 1035 | |
| 1036 | return distinct |
| 1037 |