def create(self, validated_data): # XXX: This behavior is wrong for services with several resources, find a better approach resource_class = SupportedServices.get_related_models( validated_data['service'])['resources'][0] validated_data[ 'resource_content_type'] = ContentType.objects.get_for_model( resource_class) return super(PriceListItemSerializer, self).create(validated_data)
def clean(self): if not self.service: raise ValidationError(_('Service is not defined.')) if SupportedServices.is_public_service(self.service): raise ValidationError( _('Public service does not support price list items.')) resource = self.default_price_list_item.resource_content_type.model_class( ) valid_resources = SupportedServices.get_related_models( self.service)['resources'] if resource not in valid_resources: raise ValidationError( _('Service does not support required content type.'))
def get_backend(self, service): # project_uuid can be supplied in order to get a list of resources # available for import (link) based on project, depends on backend implementation project_uuid = self.request.query_params.get('project_uuid') if project_uuid: spl_class = SupportedServices.get_related_models( service)['service_project_link'] try: spl = spl_class.objects.get(project__uuid=project_uuid, service=service) except: raise NotFound("Can't find project %s" % project_uuid) else: return spl.get_backend() else: return service.get_backend()
def get_queryset(self): queryset = models.DefaultPriceListItem.objects.all() service = self._find_service() if service: # Filter items by resource type resources = SupportedServices.get_related_models( service)['resources'] content_types = ContentType.objects.get_for_models( *resources).values() queryset = queryset.filter(resource_content_type__in=content_types) # Attach service-specific items price_list_items = models.PriceListItem.objects.filter( service=service) prefetch = Prefetch('pricelistitem_set', queryset=price_list_items, to_attr='service_item') queryset = queryset.prefetch_related(prefetch) return queryset
def change_price_list_items_if_default_was_changed(sender, instance, created=False, **kwargs): default_item = instance if created: # if new default item added - we create such item in for each service model = default_item.resource_content_type.model_class() service_class = SupportedServices.get_related_models(model)['service'] for service in service_class.objects.all(): models.PriceListItem.objects.create( resource_content_type=default_item.resource_content_type, service=service, key=default_item.key, item_type=default_item.item_type, units=default_item.units, value=default_item.value) else: if default_item.tracker.has_changed( 'key') or default_item.tracker.has_changed('item_type'): # if default item key or item type was changed - it will be changed in each connected item connected_items = models.PriceListItem.objects.filter( key=default_item.tracker.previous('key'), item_type=default_item.tracker.previous('item_type'), resource_content_type=default_item.resource_content_type, ) else: # if default value or units changed - it will be changed in each connected item # that was not edited manually connected_items = models.PriceListItem.objects.filter( key=default_item.key, item_type=default_item.item_type, resource_content_type=default_item.resource_content_type, is_manually_input=False, ) connected_items.update(key=default_item.key, item_type=default_item.item_type, units=default_item.units, value=default_item.value)