def to_representation(self, obj): """Return only the first items in the column_raw and column_mapped""" result = super(ColumnMappingSerializer, self).to_representation(obj) if obj.column_raw and obj.column_raw.first(): result['column_raw'] = ColumnSerializer(obj.column_raw.first()).data if obj.column_mapped and obj.column_mapped.first(): result['column_mapped'] = ColumnSerializer(obj.column_mapped.first()).data return result
def retrieve(self, request, pk=None): """ This API endpoint retrieves a Column """ organization_id = self.get_organization(self.request) # check if column exists for the organization try: c = Column.objects.get(pk=pk) except Column.DoesNotExist: return JsonResponse( { 'status': 'error', 'message': 'column with id {} does not exist'.format(pk) }, status=status.HTTP_404_NOT_FOUND) if c.organization.id != organization_id: return JsonResponse( { 'status': 'error', 'message': 'Organization ID mismatch between column and organization' }, status=status.HTTP_400_BAD_REQUEST) return JsonResponse({ 'status': 'success', 'column': ColumnSerializer(c).data })
def retrieve(self, request, pk=None): """ Retrieves a column (Column) type: status: required: true type: string description: Either success or error column: required: true type: dictionary description: Returns a dictionary of a full column structure with keys such as keys ''name'', ''id'', ''is_extra_data'', ''column_name'', ''table_name'',... parameters: - name: organization_id description: The organization_id for this user's organization required: true paramType: query """ organization_id = self.get_organization(self.request) # check if column exists for the organization try: c = Column.objects.get(pk=pk) except Column.DoesNotExist: return JsonResponse( { 'status': 'error', 'message': 'column with id {} does not exist'.format(pk) }, status=status.HTTP_404_NOT_FOUND) if c.organization.id != organization_id: return JsonResponse( { 'status': 'error', 'message': 'Organization ID mismatch between column and organization' }, status=status.HTTP_400_BAD_REQUEST) return JsonResponse({ 'status': 'success', 'column': ColumnSerializer(c).data })
def retrieve_mapping_columns(org_id, inventory_type=None): """ Retrieve all the columns that are for mapping for an organization in a dictionary. :param org_id: org_id, Organization ID :param inventory_type: Inventory Type (property|taxlot) from the requester. This sets the related columns if requested. :return: list, list of dict """ from seed.serializers.columns import ColumnSerializer columns_db = Column.objects.filter(organization_id=org_id).exclude( table_name='').exclude(table_name=None) columns = [] for c in columns_db: if c.column_name in Column.COLUMN_EXCLUDE_FIELDS or c.column_name in Column.EXCLUDED_MAPPING_FIELDS: continue # Eventually move this over to Column serializer directly new_c = ColumnSerializer(c).data if inventory_type: related = not (inventory_type.lower() in new_c['table_name'].lower()) if related: continue if inventory_type == 'property' and c.column_name in Column.UNMAPPABLE_PROPERTY_FIELDS: continue elif inventory_type == 'taxlot' and c.column_name in Column.UNMAPPABLE_TAXLOT_FIELDS: continue new_c['sharedFieldType'] = new_c['shared_field_type'] del new_c['shared_field_type'] if (new_c['table_name'], new_c['column_name']) in Column.PINNED_COLUMNS: new_c['pinnedLeft'] = True # If no display name, use the column name (this is the display name as it was typed # during mapping) if not new_c['display_name']: new_c['display_name'] = new_c['column_name'] columns.append(new_c) # Sort by display name columns.sort(key=lambda col: col['display_name'].lower()) return columns
def add_column_names(self, request): """ Allow columns to be added based on an existing record. This may be necessary to make column selections available when records are upload through API endpoint rather than the frontend. """ model_obj = None org = self.get_organization(request, return_obj=True) inventory_pk = request.query_params.get('inventory_pk') inventory_type = request.query_params.get('inventory_type', 'property') if inventory_type in ['property', 'propertystate']: if not inventory_pk: model_obj = PropertyState.objects.filter( organization=org ).order_by('-id').first() try: model_obj = PropertyState.objects.get(id=inventory_pk) except PropertyState.DoesNotExist: pass elif inventory_type in ['taxlot', 'taxlotstate']: if not inventory_pk: model_obj = TaxLotState.objects.filter( organization=org ).order_by('-id').first() else: try: model_obj = TaxLotState.objects.get(id=inventory_pk) inventory_type = 'taxlotstate' except TaxLotState.DoesNotExist: pass else: msg = "{} is not a valid inventory type".format(inventory_type) raise ParseError(msg) if not model_obj: msg = "No {} was found matching {}".format( inventory_type, inventory_pk ) raise NotFound(msg) Column.save_column_names(model_obj) columns = Column.objects.filter( organization=model_obj.organization, table_name=model_obj.__class__.__name__, is_extra_data=True, ) columns = ColumnSerializer(columns, many=True) return Response(columns.data, status=status.HTTP_200_OK)
def retrieve_all(org_id, inventory_type=None, only_used=False): """ Retrieve all the columns for an organization. This method will query for all the columns in the database assigned to the organization. It will then go through and cleanup the names to ensure that there are no duplicates. The name column is used for uniquely labeling the columns for UI Grid purposes. :param org_id: Organization ID :param inventory_type: Inventory Type (property|taxlot) from the requester. This sets the related columns if requested. :param only_used: View only the used columns that exist in the Column's table :return: dict """ from seed.serializers.columns import ColumnSerializer # Grab all the columns out of the database for the organization that are assigned to a # table_name. Order extra_data last so that extra data duplicate-checking will happen after # processing standard columns columns_db = Column.objects.filter(organization_id=org_id).exclude( table_name='').exclude(table_name=None).order_by( 'is_extra_data', 'column_name') columns = [] for c in columns_db: if c.column_name in Column.EXCLUDED_COLUMN_RETURN_FIELDS: continue # Eventually move this over to Column serializer directly new_c = ColumnSerializer(c).data new_c['sharedFieldType'] = new_c['shared_field_type'] del new_c['shared_field_type'] if (new_c['table_name'], new_c['column_name']) in Column.PINNED_COLUMNS: new_c['pinnedLeft'] = True # If no display name, use the column name (this is the display name as it was typed # during mapping) if not new_c['display_name']: new_c['display_name'] = new_c['column_name'] # Related fields new_c['related'] = False if inventory_type: new_c['related'] = not (inventory_type.lower() in new_c['table_name'].lower()) if new_c['related']: # if it is related then have the display name show the other table new_c['display_name'] = new_c[ 'display_name'] + ' (%s)' % INVENTORY_DISPLAY[ new_c['table_name']] # only add the column if it is in a ColumnMapping object if only_used: if ColumnMapping.objects.filter(column_mapped=c).exists(): columns.append(new_c) else: columns.append(new_c) # import json # print(json.dumps(columns, indent=2)) # validate that the field 'name' is unique. uniq = set() for c in columns: if (c['table_name'], c['column_name']) in uniq: raise Exception("Duplicate name '{}' found in columns".format( c['name'])) else: uniq.add((c['table_name'], c['column_name'])) return columns