def post_save_handler(sender, **kwargs): instance = kwargs['instance'] # Find mappings & (re-)index the instance for all of them. for dt in DocType.for_ct(get_ct(instance)): for mapping in dt.docindexmapping_set.all(): mapping.maybe_index_doc(instance)
def create(model, doc_mfield, doc_type_name, dfield, dfield_type): dt = DocType.objects.get(name=doc_type_name, content_type=get_ct(model), mfield=doc_mfield) DocIndexMapping.objects.get_or_create( doc_type=dt, dfield=dfield, dfield_type=dfield_type)
def has_mapped_doc_index(model): if not has_doc_index(model): return False for dt in DocType.for_ct(get_ct(model)): if dt.docindexmapping_set.count() > 0: return True else: return False
def mappings(model=None, doc_mfield=None, doc_type_name=None, dfield=None): fil = {} if model: fil['doc_type__content_type'] = get_ct(model) if doc_mfield: fil['doc_type__mfield'] = mfield if doc_type_name: fil['doc_type__name'] = doc_type_name if dfield: fil['dfield'] = dfield return DocIndexMapping.objects.filter(**fil)
def maybe_index_doc(self, obj, new_mapping=False): # A simple typecheck first: refuse to index a document if it's # of the wrong type. type_mfield = get_doc_metadata( obj.__class__, self.doc_type.mfield, key='type_mfield') if getattr(obj, type_mfield) != self.doc_type.name: return False # Find the field name parts = self.dfield.split('.') doc = getattr(obj, self.doc_type.mfield) try: value = reduce(lambda doc, p: doc[p], parts, doc) except KeyError: # Option to be strict? return False # We cannot refer to `content_object' directly, see: # http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ ct = get_ct(obj.__class__) if new_mapping: r = DocIndexRow(mapping=self, content_type=ct, object_id=obj.id) else: try: r = DocIndexRow.objects.get( mapping=self, content_type__pk=ct.id, object_id=obj.id) except DocIndexRow.DoesNotExist: r = DocIndexRow(mapping=self, content_type=ct, object_id=obj.id) setattr(r, 'key_%s' % self.dfield_type, coerce_field(self.dfield_type, value)) r.save() return True
def _ct(self): return get_ct(self.model)
def make(name, model, mfield): return DocType.objects.get_or_create( name=name, content_type=get_ct(model), mfield=mfield)[0]