def init_auditlog(): """Init auditlog""" if settings.TX_DISABLE_AUDITLOG: return for config in models_config.get_all_configs(False): if config.auditlog_disable or ( not config.is_trionyx_model and not config.has_config('auditlog_disable')): continue post_save.connect(log_add, sender=config.model, dispatch_uid=(log_add, config.model, post_save)) pre_save.connect(log_change, sender=config.model, dispatch_uid=(log_change, config.model, pre_save)) post_delete.connect(log_delete, sender=config.model, dispatch_uid=(log_delete, config.model, post_delete)) @tabs.register(config.model, code='history', name=_('History'), order=999) def layout(obj): return auditlog_layout(obj)
def auto_generate_missing_tabs(self): """Auto generate tabs for models with no tabs""" for config in models_config.get_all_configs(False): model_alias = self.get_model_alias(config.model) if model_alias not in self.tabs: @self.register(model_alias, order=10) def general_layout(obj): return Layout( Column12( Panel( 'info', DescriptionList(*[ f.name for f in models_config.get_config( obj).get_fields() ]))))
def auto_regiser_models(self): """Auto register all models""" # Load serializers for app in apps.get_app_configs(): for module in ['serializers', 'api.serializers']: try: import_module('{}.{}'.format(app.module.__package__, module)) except ImportError: pass for config in models_config.get_all_configs(): if config.api_disable: continue model = config.model basename = model._meta.object_name.lower() classname = model.__name__ serializer = serializer_register.get(model) serializer = serializer if serializer else self.generate_model_serializer( model, config) if [ name for name, field in serializer().get_fields().items() if not field.read_only ]: base_classes = (ModelViewSet, ) else: base_classes = (mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.DestroyModelMixin, GenericViewSet) DynamicViewSet = type(classname, base_classes, {}) DynamicViewSet.model = model DynamicViewSet.queryset = model.objects.get_queryset() DynamicViewSet.serializer_class = serializer DynamicViewSet.permission_classes = ( ExtendedDjangoModelPermissions, ) DynamicViewSet.ordering = ['pk'] DynamicViewSet.schema = APIAutoSchema( tags=[config.get_verbose_name_plural()]) self.register(self.get_model_prefix(model), DynamicViewSet, basename)
def handle_request(self, request): """Handle search""" models = [] content_types = {} for config in models_config.get_all_configs(False): if config.disable_search_index or not config.global_search: continue # Check if user has view permission if not request.user.has_perm( '{app_label}.view_{model_name}'.format( app_label=config.app_label, model_name=config.model_name, ).lower()): continue models.append(config.model) content_type = ContentType.objects.get_for_model( config.model, False) content_types[content_type.id] = str( config.model._meta.verbose_name_plural) results = OrderedDict() for entry in watson.search(request.GET.get('search', ''), models=models)[:100]: if entry.content_type_id not in results: results[entry.content_type_id] = { 'name': content_types[entry.content_type_id], 'items': [], } if len(results[entry.content_type_id]['items']) <= 10: results[entry.content_type_id]['items'].append({ 'url': entry.url, 'title': entry.title, 'description': entry.description, }) return list(results.values())
def get_schema(self, *args, **kwargs): """Extend schema""" schema = super().get_schema(*args, **kwargs) schema['components'] = { 'securitySchemes': { "Api token": { "type": "apiKey", "name": "Authorization", "in": "header", "bearerFormat": 'Token', 'description': """{} Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b""".format( _('The key should be prefixed by the string literal **"Token"**, with whitespace separating the two strings. For example:' ), # noqa E501 ), }, } } groups = defaultdict(list) for config in models_config.get_all_configs(): if config.api_disable: continue group_name = str(config.app_config.verbose_name) groups[group_name].append(config.get_verbose_name_plural(True)) groups[group_name].sort() # TODO for custom views: add user defined groups and add custom tag to existing group schema['x-tagGroups'] = [{ 'name': name, 'tags': groups[name], } for name in sorted(groups)] return schema
def get_data(self, request: HttpRequest, config: dict) -> List[dict]: """Get data for widget""" content_type_ids = [ content_type.id for model, content_type in ContentType.objects.get_for_models(*[ config.model for config in models_config.get_all_configs(False) if request.user.has_perm( '{app_label}.view_{model_name}'.format( app_label=config.app_label, model_name=config.model_name, ).lower()) ]).items() ] logs = AuditLogEntry.objects.filter( content_type__in=content_type_ids).prefetch_related('user') show = config.get('show', 'all') if show != 'all': logs = logs.filter(user__isnull=show == 'system') return [ { 'user_full_name': log.user.get_full_name() if log.user else _('System'), 'user_avatar': log.user.avatar.url if log.user and log.user.avatar else static('img/avatar.png'), 'action': renderer.render_field(log, 'action'), 'object': '({}) {}'.format( str(log.content_type.model_class()._meta.verbose_name). capitalize(), # type: ignore log.object_verbose_name), 'object_url': log.content_object.get_absolute_url() if log.content_object else '', 'created_at': renderer.render_field(log, 'created_at'), } for log in logs.order_by('-created_at')[:6] ]
def __init__(self, *args, **kwargs): """Init form""" super().__init__(*args, **kwargs) from trionyx.widgets import widget_data, GraphWidget self.fields['source'].choices = [ ('', '------'), *[(code, data['name']) for code, data in widget_data.get_all_data(GraphWidget).items()], ('__custom__', _('Custom')) ] content_type_map = ContentType.objects.get_for_models( *list(models_config.get_all_models(utils.get_current_user()))) interval_fields = {} graph_fields = {} for config in models_config.get_all_configs(): if config.model not in content_type_map: continue graph_fields[content_type_map[config.model].id] = [{ 'id': '__count__', 'text': str(_('Count records')), }, *[{ 'id': field.name, 'text': str(field.verbose_name) } for field in config.get_fields() if config.get_field_type(field) in ['int', 'float']]] interval_fields[content_type_map[config.model].id] = [ { 'id': field.name, 'text': str(field.verbose_name) } for field in config.get_fields(True) if config.get_field_type(field) in ['date', 'datetime'] ] self.fields['model'].choices = [ (content_type.id, model._meta.verbose_name.capitalize()) for model, content_type in content_type_map.items() ] self.helper = FormHelper() self.helper.layout = Layout( 'source', Depend([('source', r'__custom__')], 'icon', Div(Div( 'model', css_class="col-md-6", ), Div( HtmlTemplate( 'widgets/forms/model_field.html', { 'model_id': '#id_model', 'label': _('Field'), 'name': 'field', 'fields': graph_fields, 'value': self.initial.get('field'), }), css_class="col-md-6", ), css_class="row"), Div(Div( HtmlTemplate( 'widgets/forms/model_field.html', { 'model_id': '#id_model', 'label': _('Interval field'), 'name': 'interval_field', 'fields': interval_fields, 'value': self.initial.get('interval_field'), }), css_class="col-md-6", ), Div( 'interval_period', css_class="col-md-6", ), css_class="row"), Fieldset( _('Filters'), Filters('filters', content_type_input_id='id_model'), ), css_id='widget-custom-source'))