# -*- coding: utf-8 -*- from __future__ import unicode_literals import os.path from django.utils import six from django.db import models from django import template from django.urls import ( NoReverseMatch, reverse, ) from django.utils.html import escape from django.utils.safestring import mark_safe from cruds import utils register = template.Library() @register.filter def get_attr(obj, attr): """ Filter returns obj attribute. """ return getattr(obj, attr) @register.simple_tag def crud_url(obj, action): try: url = reverse( utils.crud_url_name(type(obj), action), kwargs={'pk': obj.pk}) except NoReverseMatch: url = None return url def format_value_instance(value): url = crud_url(value, utils.ACTION_DETAIL) if url: return mark_safe('<a href="%s">%s</a>' % (url, escape(value))) if hasattr(value, 'get_absolute_url'): url = getattr(value, 'get_absolute_url')() return mark_safe('<a href="%s">%s</a>' % (url, escape(value))) return value @register.filter def format_value(obj, field_name): """ Simple value formatting. If value is model instance returns link to detail view if exists. """ display_func = getattr(obj, 'get_%s_display' % field_name, None) if display_func: return display_func() value = getattr(obj, field_name) if isinstance(value, models.fields.files.FieldFile): if value: return mark_safe('<a href="%s">%s</a>' % ( value.url, os.path.basename(value.name), )) else: return '' if isinstance(value, models.Model): return format_value_instance(value) if isinstance(value, models.Manager): return mark_safe(', '.join( [format_value_instance(instance) for instance in value.all()] )) if value is None: value = "" return value @register.inclusion_tag('cruds/templatetags/crud_fields.html') def crud_fields(obj, fields=None): """ Display object fields in table rows:: <table> {% crud_fields object 'id, %} </table> * ``fields`` fields to include If fields is ``None`` all fields will be displayed. If fields is ``string`` comma separated field names will be displayed. if field is dictionary, key should be field name and value field verbose name. """ if fields is None: fields = utils.get_fields(type(obj)) elif isinstance(fields, six.string_types): field_names = [f.strip() for f in fields.split(',')] fields = utils.get_fields(type(obj), include=field_names) return { 'object': obj, 'fields': fields, } @register.simple_tag def get_fields(model, fields=None): """ Assigns fields for model. """ include = [f.strip() for f in fields.split(',')] if fields else None return utils.get_fields( model, include )