def process_document(self, document, form_key, passed_key): """ Given the form_key will evaluate the document and set values correctly for the document given. """ if passed_key is not None: current_key, remaining_key_array = trim_field_key(document, passed_key) else: current_key, remaining_key_array = trim_field_key(document, form_key) key_array_digit = remaining_key_array[-1] if remaining_key_array and has_digit(remaining_key_array) else None remaining_key = make_key(remaining_key_array) if current_key.lower() == "id": raise KeyError(u"Mongonaut does not work with models which have fields beginning with id_") # Create boolean checks to make processing document easier is_embedded_doc = ( isinstance(document._fields.get(current_key, None), EmbeddedDocumentField) if hasattr(document, "_fields") else False ) is_list = not key_array_digit is None key_in_fields = current_key in document._fields.keys() if hasattr(document, "_fields") else False # This ensures you only go through each documents keys once, and do not duplicate data if key_in_fields: if is_embedded_doc: self.set_embedded_doc(document, form_key, current_key, remaining_key) elif is_list: self.set_list_field(document, form_key, current_key, remaining_key, key_array_digit) else: value = translate_value(document._fields[current_key], self.form.cleaned_data[form_key]) setattr(document, current_key, value)
def process_document(self, document, form_key, passed_key): """ Given the form_key will evaluate the document and set values correctly for the document given. """ if passed_key is not None: current_key, remaining_key_array = trim_field_key(document, passed_key) else: current_key, remaining_key_array = trim_field_key(document, form_key) key_array_digit = remaining_key_array[-1] if remaining_key_array and has_digit(remaining_key_array) else None remaining_key = make_key(remaining_key_array) if current_key.lower() == 'id': raise KeyError(u"Mongonaut does not work with models which have fields beginning with id_") # Create boolean checks to make processing document easier is_embedded_doc = (isinstance(document._fields.get(current_key, None), EmbeddedDocumentField) if hasattr(document, '_fields') else False) is_list = not key_array_digit is None key_in_fields = current_key in document._fields.keys() if hasattr(document, '_fields') else False # This ensures you only go through each documents keys once, and do not duplicate data if key_in_fields: if is_embedded_doc: self.set_embedded_doc(document, form_key, current_key, remaining_key) elif is_list: self.set_list_field(document, form_key, current_key, remaining_key, key_array_digit) else: value = translate_value(document._fields[current_key], self.form.cleaned_data[form_key]) setattr(document, current_key, value)
def get_value(document, field_key): # Short circuit the function if we do not have a document if document is None: return None current_key, new_key_array = trim_field_key(document, field_key) key_array_digit = int( new_key_array[-1] ) if new_key_array and has_digit(new_key_array) else None new_key = make_key(new_key_array) if key_array_digit is not None and len(new_key_array) > 0: # Handling list fields if len(new_key_array) == 1: return_data = document._data.get(current_key, []) elif isinstance(document, BaseList): return_list = [] if len(document) > 0: return_list = [ get_value(doc, new_key) for doc in document ] return_data = return_list else: return_data = get_value(getattr(document, current_key), new_key) elif len(new_key_array) > 0: return_data = get_value(document._data.get(current_key), new_key) else: # Handeling all other fields and id return_data = (document._data.get(None, None) if current_key == "id" else document._data.get( current_key, None)) return return_data
def get_value(document, field_key): # Short circuit the function if we do not have a document if document is None: return None current_key, new_key_array = trim_field_key(document, field_key) key_array_digit = int(new_key_array[-1]) if new_key_array and has_digit(new_key_array) else None new_key = make_key(new_key_array) if key_array_digit is not None and len(new_key_array) > 0: # Handleing list fields if len(new_key_array) == 1: return_data = document._data.get(current_key, []) elif isinstance(document, BaseList): return_list = [] if len(document) > 0: return_list = [get_value(doc, new_key) for doc in document] return_data = return_list else: return_data = get_value(getattr(document, current_key), new_key) elif len(new_key_array) > 0: return_data = get_value(document._data.get(current_key), new_key) else: # Handeling all other fields and id return_data = (document._data.get(None, None) if current_key == "id" else document._data.get(current_key, None)) return return_data
def set_embedded_doc(self, document, form_key, current_key, remaining_key): # Get the existing embedded document if it exists, else created it. embedded_doc = getattr(document, current_key, False) if not embedded_doc: embedded_doc = document._fields[current_key].document_type_obj() new_key, new_remaining_key_array = trim_field_key(embedded_doc, remaining_key) self.process_document(embedded_doc, form_key, make_key(new_key, new_remaining_key_array)) setattr(document, current_key, embedded_doc)
def set_list_field(self, document, form_key, current_key, remaining_key, key_array_digit): """1. Figures out what value the list ought to have 2. Sets the list """ document_field = document._fields.get(current_key) # Figure out what value the list ought to have # None value for ListFields make mongoengine very un-happy list_value = translate_value(document_field.field, self.form.cleaned_data[form_key]) if list_value is None or (not list_value and not bool(list_value)): return None current_list = getattr(document, current_key, None) if isinstance(document_field.field, EmbeddedDocumentField): embedded_list_key = u"{0}_{1}".format(current_key, key_array_digit) # Get the embedded document if it exists, else create it. embedded_list_document = self.embedded_list_docs.get( embedded_list_key, None) if embedded_list_document is None: embedded_list_document = document_field.field.document_type_obj( ) new_key, new_remaining_key_array = trim_field_key( embedded_list_document, remaining_key) self.process_document(embedded_list_document, form_key, new_key) list_value = embedded_list_document self.embedded_list_docs[embedded_list_key] = embedded_list_document if isinstance(current_list, list): # Do not add the same document twice if embedded_list_document not in current_list: current_list.append(embedded_list_document) else: setattr(document, current_key, [embedded_list_document]) elif isinstance(current_list, list): current_list.append(list_value) else: setattr(document, current_key, [list_value])
def get_value(document, field_key): # Short circuit the function if we do not have a document if document is None: return None current_key, new_key_array = trim_field_key(document, field_key) key_array_digit = int( new_key_array[-1] ) if new_key_array and has_digit(new_key_array) else None new_key = make_key(new_key_array) if key_array_digit is not None and len(new_key_array) > 0: # Handleing list fields if len(new_key_array) == 1: return_data = document._data.get(current_key, []) elif isinstance(document, BaseList): return_list = [] if len(document) > 0: return_list = [ get_value(doc, new_key) for doc in document ] return_data = return_list else: return_data = get_value(getattr(document, current_key), new_key) elif len(new_key_array) > 0: return_data = get_value(document._data.get(current_key), new_key) else: # Handeling all other fields and id try: # Added try except otherwise we get "TypeError: getattr(): attribute name must be string" error from mongoengine/base/datastructures.py return_data = (document._data.get(None, None) if current_key == "id" else document._data.get( current_key, None)) except: return_data = document._data.get(current_key, None) return return_data
def set_list_field(self, document, form_key, current_key, remaining_key, key_array_digit): document_field = document._fields.get(current_key) # Figure out what value the list ought to have # None value for ListFields make mongoengine very un-happy list_value = translate_value(document_field.field, self.form.cleaned_data[form_key]) if list_value is None or (not list_value and not bool(list_value)): return None current_list = getattr(document, current_key, None) if isinstance(document_field.field, EmbeddedDocumentField): embedded_list_key = u"{0}_{1}".format(current_key, key_array_digit) # Get the embedded document if it exists, else create it. embedded_list_document = self.embedded_list_docs.get(embedded_list_key, None) if embedded_list_document is None: embedded_list_document = document_field.field.document_type_obj() new_key, new_remaining_key_array = trim_field_key(embedded_list_document, remaining_key) self.process_document(embedded_list_document, form_key, new_key) list_value = embedded_list_document self.embedded_list_docs[embedded_list_key] = embedded_list_document if isinstance(current_list, list): # Do not add the same document twice if embedded_list_document not in current_list: current_list.append(embedded_list_document) else: setattr(document, current_key, [embedded_list_document]) elif isinstance(current_list, list): current_list.append(list_value) else: setattr(document, current_key, [list_value])