def finalize_response(self, request, response, *args, **kwargs): response = super(BaseLoggingMixin, self).finalize_response(request, response, *args, **kwargs) # Ensure backward compatibility for those using _should_log hook should_log = (self._should_log if hasattr(self, "_should_log") else self.should_log) if should_log(request, response): if (connection.settings_dict.get("ATOMIC_REQUESTS") and getattr(response, "exception", None) and connection.in_atomic_block): # response with exception (HTTP status like: 401, 404, etc) # pointwise disable atomic block for handle log (TransactionManagementError) connection.set_rollback(True) connection.set_rollback(False) if response.streaming: rendered_content = None elif hasattr(response, "rendered_content"): rendered_content = response.rendered_content else: rendered_content = response.getvalue() self.log.update({ "remote_addr": self._get_ip_address(request), "view": self._get_view_name(request), "view_method": self._get_view_method(request), "path": self._get_path(request), "host": request.get_host(), "method": request.method, "query_params": self._clean_data(request.query_params.dict()), "user": self._get_user(request), "username_persistent": self._get_user(request).get_username() if self._get_user(request) else "Anonymous", "response_ms": self._get_response_ms(), "response": self._clean_data(rendered_content), "status_code": response.status_code, }) if self._clean_data(request.query_params.dict()) == {}: self.log.update({"query_params": self.log["data"]}) try: self.handle_log() except Exception: # ensure that all exceptions raised by handle_log # doesn't prevent API call to continue as expected logger.exception("Logging API call raise exception!") return response
def finalize_response(self, request, response, *args, **kwargs): response = super(BaseLoggingMixin, self).finalize_response(request, response, *args, **kwargs) # Ensure backward compatibility for those using _should_log hook should_log = self._should_log if hasattr( self, '_should_log') else self.should_log if should_log(request, response): if hasattr(response, 'rendered_content'): rendered_content = response.rendered_content else: rendered_content = response.getvalue() self.log.update({ 'remote_addr': self._get_ip_address(request), 'view': self._get_view_name(request), 'view_method': self._get_view_method(request), 'path': request.path, 'host': request.get_host(), 'method': request.method, 'query_params': self._clean_data(request.query_params.dict()), 'user': self._get_user(request), 'response_ms': self._get_response_ms(), 'response': self._clean_data(rendered_content), 'status_code': response.status_code, 'country': self._get_country(request), 'city': self._get_city(request), }) try: if not connection.settings_dict.get('ATOMIC_REQUESTS'): self.handle_log() elif response.exception and not connection.in_atomic_block or not response.exception: self.handle_log() elif response.exception: # respone with exception (HTTP status like: 401, 404, etc) # pointwise disable atomic block for handle log (TransactionManagementError) connection.set_rollback(True) connection.set_rollback(False) self.handle_log() except Exception: # ensure that all exceptions raised by handle_log # doesn't prevent API call to continue as expected logger.exception('Logging API call raise exception!') return response
def update_products(self): """ Apply sales field value to products and variations according to the selected categories and products for the sale. """ self._clear() if self.active: extra_filter = {} if self.discount_deduct is not None: # Don't apply to prices that would be negative # after deduction. extra_filter["unit_price__gt"] = self.discount_deduct sale_price = models.F("unit_price") - self.discount_deduct elif self.discount_percent is not None: sale_price = models.F("unit_price") - ( F("unit_price") / "100.0" * self.discount_percent) elif self.discount_exact is not None: # Don't apply to prices that are cheaper than the sale # amount. extra_filter["unit_price__gt"] = self.discount_exact sale_price = self.discount_exact else: return products = self.all_products() variations = ProductVariation.objects.filter(product__in=products) for priced_objects in (products, variations): update = { "sale_id": self.id, "sale_price": sale_price, "sale_to": self.valid_to, "sale_from": self.valid_from } using = priced_objects.db if "mysql" not in settings.DATABASES[using]["ENGINE"]: priced_objects.filter(**extra_filter).update(**update) else: # Work around for MySQL which does not allow update # to operate on subquery where the FROM clause would # have it operate on the same table, so we update # each instance individually: # http://dev.mysql.com/doc/refman/5.0/en/subquery-errors.html # Also MySQL may raise a 'Data truncated' warning here # when doing a calculation that exceeds the precision # of the price column. In this case it's safe to ignore # it and the calculation will still be applied, but # we need to massage transaction management in order # to continue successfully: # https://groups.google.com/forum/#!topic/django-developers/ACLQRF-71s8 for priced in priced_objects.filter(**extra_filter): for field, value in list(update.items()): setattr(priced, field, value) try: priced.save() except Warning: connection.set_rollback(False)
def update_products(self): """ Apply sales field value to products and variations according to the selected categories and products for the sale. """ self._clear() if self.active: extra_filter = {} if self.discount_deduct is not None: # Don't apply to prices that would be negative # after deduction. extra_filter["unit_price__gt"] = self.discount_deduct sale_price = models.F("unit_price") - self.discount_deduct elif self.discount_percent is not None: sale_price = models.F("unit_price") - ( F("unit_price") / "100.0" * self.discount_percent) elif self.discount_exact is not None: # Don't apply to prices that are cheaper than the sale # amount. extra_filter["unit_price__gt"] = self.discount_exact sale_price = self.discount_exact else: return products = self.all_products() variations = ProductVariation.objects.filter(product__in=products) for priced_objects in (products, variations): update = {"sale_id": self.id, "sale_price": sale_price, "sale_to": self.valid_to, "sale_from": self.valid_from} using = priced_objects.db if "mysql" not in settings.DATABASES[using]["ENGINE"]: priced_objects.filter(**extra_filter).update(**update) else: # Work around for MySQL which does not allow update # to operate on subquery where the FROM clause would # have it operate on the same table, so we update # each instance individually: # http://dev.mysql.com/doc/refman/5.0/en/subquery-errors.html # Also MySQL may raise a 'Data truncated' warning here # when doing a calculation that exceeds the precision # of the price column. In this case it's safe to ignore # it and the calculation will still be applied, but # we need to massage transaction management in order # to continue successfully: # https://groups.google.com/forum/#!topic/django-developers/ACLQRF-71s8 for priced in priced_objects.filter(**extra_filter): for field, value in list(update.items()): setattr(priced, field, value) try: priced.save() except Warning: connection.set_rollback(False)
def finalize_response(self, request, response, *args, **kwargs): response = super(BaseLoggingMixin, self).finalize_response(request, response, *args, **kwargs) # Ensure backward compatibility for those using _should_log hook should_log = self._should_log if hasattr(self, '_should_log') else self.should_log if should_log(request, response): if response.streaming: rendered_content = None elif hasattr(response, 'rendered_content'): rendered_content = response.rendered_content else: rendered_content = response.getvalue() user_agent = request.META.get('HTTP_USER_AGENT') self.log.update( { 'remote_addr': self._get_ip_address(request), 'view': self._get_view_name(request), 'view_method': self._get_view_method(request), 'path': request.path, 'host': request.get_host(), 'method': request.method, 'query_params': self._clean_data(request.query_params.dict()), 'user': self._get_user(request), 'username_persistent': self._get_user(request).username if self._get_user(request) else 'Anonymous', 'response_ms': self._get_response_ms(), 'response': self._clean_data(rendered_content), 'status_code': response.status_code, 'user_agent': user_agent, 'browser': httpagentparser.simple_detect(user_agent)[1], 'operating_system': httpagentparser.simple_detect(user_agent)[0] } ) if self._clean_data(request.query_params.dict()) == {}: self.log.update({'query_params': self.log['data']}) try: if not connection.settings_dict.get('ATOMIC_REQUESTS'): self.handle_log() else: if getattr(response, 'exception', None) and connection.in_atomic_block: # response with exception (HTTP status like: 401, 404, etc) # pointwise disable atomic block for handle log (TransactionManagementError) connection.set_rollback(True) connection.set_rollback(False) self.handle_log() except Exception: # ensure that all exceptions raised by handle_log # doesn't prevent API call to continue as expected logger.exception('Logging API call raise exception!') return response
def finalize_response(self, request, response, *args, **kwargs): response = super(BaseLoggingMixin, self).finalize_response(request, response, *args, **kwargs) # Ensure backward compatibility for those using _should_log hook should_log = self._should_log if hasattr(self, '_should_log') else self.should_log if should_log(request, response): if hasattr(response, 'rendered_content'): rendered_content = response.rendered_content else: rendered_content = response.getvalue() self.log.update( { 'remote_addr': self._get_ip_address(request), 'view': self._get_view_name(request), 'view_method': self._get_view_method(request), 'path': request.path, 'host': request.get_host(), 'method': request.method, 'query_params': self._clean_data(request.query_params.dict()), 'user': self._get_user(request), 'response_ms': self._get_response_ms(), 'response': self._clean_data(rendered_content), 'status_code': response.status_code, } ) try: if not connection.settings_dict.get('ATOMIC_REQUESTS'): self.handle_log() elif response.exception and not connection.in_atomic_block or not response.exception: self.handle_log() elif response.exception: # respone with exception (HTTP status like: 401, 404, etc) # pointwise disable atomic block for handle log (TransactionManagementError) connection.set_rollback(True) connection.set_rollback(False) self.handle_log() except Exception: # ensure that all exceptions raised by handle_log # doesn't prevent API call to continue as expected logger.exception('Logging API call raise exception!') return response
def finalize_response(self, request, response, *args, **kwargs): try: response = super(APILoggingMixin, self).finalize_response(request, response, *args, **kwargs) except: response = None should_log = self._should_log if hasattr( self, '_should_log') else self.should_log if should_log(request): self.log.update({ 'remote_addr': get_ip_address(request), 'view': self._get_view_name(request), 'app': str(self._get_view_name(request)), 'view_method': self._get_view_method(request), 'path': request.path, 'host': request.get_host(), 'method': request.method, 'query_params': self._clean_data(request.query_params.dict()), 'user': get_user(request), 'response_ms': get_response_ms(self.requested_at), 'token': get_token(request) }) if response: if hasattr(response, 'rendered_content'): rendered_content = response.rendered_content else: rendered_content = response.getvalue() if not rendered_content: cleaned_response = None else: cleaned_response = self._clean_data( json.loads(rendered_content.decode())) self.log.update({ 'status_code': response.status_code, 'response': cleaned_response }) try: if not connection.settings_dict.get('ATOMIC_REQUESTS'): self.handle_log() elif response.exception and not connection.in_atomic_block or not response.exception: self.handle_log() elif response.exception: connection.set_rollback(True) connection.set_rollback(False) self.handle_log() except Exception: print('Logging API call raise exception!') else: self.log.update({'response': None, 'status_code': 500}) try: self.handle_log() except Exception: print('Logging API call raise exception!') return response
def finalize_response(self, request, response, *args, **kwargs): response = super(BaseLoggingMixin, self).finalize_response(request, response, *args, **kwargs) # Ensure backward compatibility for those using _should_log hook should_log = self._should_log if hasattr( self, '_should_log') else self.should_log if should_log(request, response): if hasattr(response, 'rendered_content'): rendered_content = response.rendered_content else: rendered_content = response.getvalue() try: response_code = response.data['status']['code'] except: response_code = response.status_code try: if request.method == 'GET': log_obj = { 'headers': { str(key): str(value) for key, value in request.META.items() }, 'remote_addr': str(self._get_ip_address(request)), 'view': self._get_view_name(request), 'view_method': self._get_view_method(request), 'path': request.path, 'host': request.get_host(), 'method': request.method, 'user_agent': request.META.get('HTTP_USER_AGENT'), 'query_params': str(self._clean_data(request.query_params.dict())), 'user_id': str(self._get_user(request).id or ''), 'user_email': getattr(self._get_user(request), 'email', None) or '', 'response_ms': self._get_response_ms(), # 'response': str(self._clean_data(rendered_content)), 'status_code': response_code, } else: log_obj = { 'headers': { str(key): str(value) for key, value in request.META.items() }, 'remote_addr': str(self._get_ip_address(request)), 'view': self._get_view_name(request), 'view_method': self._get_view_method(request), 'path': request.path, 'host': request.get_host(), 'method': request.method, 'user_agent': request.META.get('HTTP_USER_AGENT'), 'query_params': str(self._clean_data(request.query_params.dict())), 'user_id': str(self._get_user(request).id or ''), 'user_email': getattr(self._get_user(request), 'email', None) or '', 'response_ms': self._get_response_ms(), 'response': str(self._clean_data(rendered_content)), 'status_code': response_code, } self.log.update(log_obj) if not connection.settings_dict.get('ATOMIC_REQUESTS'): self.handle_log() elif response.exception and not connection.in_atomic_block or not response.exception: self.handle_log() elif response.exception: # respone with exception (HTTP status like: 401, 404, etc) # pointwise disable atomic block for handle log (TransactionManagementError) connection.set_rollback(True) connection.set_rollback(False) self.handle_log() except Exception: # ensure that all exceptions raised by handle_log # doesn't prevent API call to continue as expected logger.exception('Logging API call raise exception!') return response