text: import datetime
  from django import forms
  from django.contrib import admin
  from django.contrib.admin import SimpleListFilter
  from django.urls import reverse
  from ordered_model.admin import OrderedTabularInline
  from solo.admin import SingletonModelAdmin
  from taggit.models import Tag
  from taggit_helpers.admin import TaggitListFilter
  from import_export import resources, fields
  from import_export.admin import ExportActionModelAdmin
  from import_export.fields import Field
  from import_export.formats import base_formats
  
  from pompom.apps.huddle_board.forms import CardForm, DeckForm
  from .models import Card, CardSection, Observation, Answer, Board, Deck, \
      CardNote, SafetyMessage, SiteConfiguration
  
  from django.contrib.sessions.models import Session
  
  @admin.register(Session)
  class SessionAdmin(admin.ModelAdmin):
      def _session_data(self, obj):
          return obj.get_decoded()
      list_display = ['session_key', '_session_data', 'expire_date']
  
  
  class DateFilter(SimpleListFilter):
      title = 'date'
      parameter_name = 'dates'
  
      def lookups(self, request, model_admin):
          return [
              ('today', 'Today'),
              ('this_month', 'Month to date'),
              ('last_month', 'Last month'),
              ('this_year', 'This year'),
              ('last_year', 'Last year')
              ]
  
      def queryset(self, request, queryset):
          if self.value() == 'this_year':
              try:
                  query = queryset.filter(created__year=datetime.date.today().year)
              except Exception:
                  query = queryset.filter(observation__created__year=datetime.date.today().year)
          if self.value() == 'today':
              try:
                  query = queryset.filter(created__day=datetime.date.today().day)
              except Exception:
                  query = queryset.filter(observation__created__day=datetime.date.today().day)
          if self.value() == 'last_month':
              try:
                  query = queryset.filter(created__month=datetime.date.today().month-1)
              except Exception:
                  query = queryset.filter(observation__created__month=datetime.date.today().month-1)
          if self.value() == 'this_month':
              try:
                  query = queryset.filter(created__month=datetime.date.today().month)
              except Exception:
                  query = queryset.filter(observation__created__month=datetime.date.today().month)
          try:
              return query
          except Exception:
              return queryset
  
  
  class ObservationResource(resources.ModelResource):
      date = fields.Field(column_name='Date')
      board = fields.Field(column_name='Board')
      card_id = fields.Field(column_name='Card ID ')
      title = fields.Field(column_name='Card')
      result = fields.Field(column_name='Result')
  
      class Meta:
          model = Observation
          fields = ('board',)
  
      def dehydrate_date(self, observation):
          return observation.__str__()
  
      def dehydrate_title(self, observation):
          return observation.card
  
      def dehydrate_card_id(self, observation):
          return observation.card.id
  
      def dehydrate_result(self, observation):
          grade = {True: 'Pass', False: 'Fallout', None: 'N/A'}
          return grade[observation.grade()]
  
      def dehydrate_board(self, observation):
          return observation.board
  
  
  class AnswerResource(resources.ModelResource):
      observation = fields.Field(column_name='Date')
      board = fields.Field(column_name='Board')
      card_id = fields.Field(column_name='Card ID    ')
      card = fields.Field(column_name='Card')
      card_section_id = fields.Field(column_name='Element ID  ')
      card_section = fields.Field(column_name='Element Title ')
      grade = fields.Field(column_name='Result')
  
      class Meta:
          model = Answer
          fields = ()
  
      def get_queryset(self):
          return self._meta.model.objects.order_by('observation__board')
  
      def dehydrate_card_id(self, answer):
          return answer.card_section.card.id
  
      def dehydrate_card_section_id(self, answer):
          return answer.card_section.id
  
      def dehydrate_board(self, answer):
          return answer.observation.board
  
      def dehydrate_observation(self, answer):
          return answer.observation
  
      def dehydrate_card_section(self, answer):
          return answer.card_section
  
      def dehydrate_grade(self, answer):
          grade = {True: 'Pass', False: 'Fallout', None: 'N/A'}
          return grade[answer.grade]
  
      def dehydrate_card(self, answer):
          return answer.card_section.card.title
  
  
  class CardNoteResource(resources.ModelResource):
      date = fields.Field(column_name='Date')
      board = fields.Field(column_name='Board')
      card_id = fields.Field(column_name='Card ID    ')
      card = fields.Field(column_name='Card')
      notes = fields.Field(column_name='Notes')
  
      class Meta:
          model = CardNote
          fields = ('date', 'board', 'card_id', 'card', 'notes')
  
      def get_queryset(self):
          return self._meta.model.objects.order_by('board')
  
      def dehydrate_card_id(self, cardnote):
          return cardnote.card.id
  
      def dehydrate_board(self, cardnote):
          return cardnote.board
  
      def dehydrate_card(self, cardnote):
          return cardnote.card.title
  
      def dehydrate_notes(self, cardnote):
          return cardnote
  
      def dehydrate_date(self, cardnote):
          return cardnote.get_created()
  
  
  class CardSectionInline(OrderedTabularInline):
      model = CardSection
      fields = ('title', 'contents', 'is_gradable', 'check_count', 'order', 'move_up_down_links',)
      readonly_fields = ('order', 'move_up_down_links',)
      extra = 1
      ordering = ('order',)
  
      def formfield_for_dbfield(self, db_field, request, **kwargs):
          formfield = super().formfield_for_dbfield(db_field, request, **kwargs)
          if db_field.name == 'title':
              formfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
          return formfield
  
  
  @admin.register(Card)
  class CardAdmin(admin.ModelAdmin):
      form = CardForm
      inlines = (CardSectionInline, )
      list_display = ['title', 'tag_list']
      list_filter = [TaggitListFilter, DateFilter]
  
      def get_queryset(self, request):
          return super().get_queryset(request).prefetch_related('tags')
  
      def get_urls(self):
          urls = super().get_urls()
          for inline in self.inlines:
              if hasattr(inline, 'get_urls'):
                  urls = inline.get_urls(self) + urls
          return urls
  
  
  class AnswerInline(admin.TabularInline):
      model = Answer
      fields = ('card_section', 'grade', 'checks_done')
      extra = 0
  
  
  @admin.register(Observation)
  class ObservationAdmin(ExportActionModelAdmin, admin.ModelAdmin):
      fields = ('created', 'board', 'card')
      readonly_fields = ('created',)
      inlines = (AnswerInline, )
      list_display = ('id', 'card', 'board', 'created')
      list_filter = ('card', 'board', DateFilter)
      resource_class = ObservationResource
  
      def get_export_formats(self):
          formats = (
              base_formats.CSV,
              base_formats.XLSX,
          )
          return [f for f in formats if f().can_export()]
  
  
  @admin.register(Board)
  class BoardAdmin(admin.ModelAdmin):
      list_display = ('title', 'description', 'deck')
  
  
  @admin.register(Deck)
  class DeckAdmin(admin.ModelAdmin):
      form = DeckForm
      list_display = ('title', 'description', 'boards_using_this_deck')
      readonly_fields = ('boards_using_this_deck', )
      filter_horizontal = ('cards', )
  
      def boards_using_this_deck(self, deck):
          return ", ".join([self.board_url(board) for board in deck.board_set.all()]) or "-"
      boards_using_this_deck.allow_tags = True
  
      def board_url(self, board):
          board_admin_url = reverse('admin:huddle_board_board_change', args=[board.id])
          return '<a href="{url}">{title}</a>'.format(url=board_admin_url, title=board.title)
  
      def get_queryset(self, request):
          return super().get_queryset(request).prefetch_related('board_set')
  
  
  @admin.register(CardNote)
  class CardNoteAdmin(ExportActionModelAdmin, admin.ModelAdmin):
      list_display = ('to_string', 'card', 'board', 'created')
      list_filter = ('board', 'card', DateFilter)
      resource_class = CardNoteResource
  
      def get_export_formats(self):
          formats = (
              base_formats.CSV,
              base_formats.XLSX,
          )
          return [f for f in formats if f().can_export()]
  
      def to_string(self, obj):
          return str(obj)
      to_string.short_description = 'Contents'
  
  
  @admin.register(SafetyMessage)
  class SafetyMessageAdmin(admin.ModelAdmin):
      list_display = ('to_string', 'created', 'modified')
  
      def to_string(self, obj):
          return str(obj)
      to_string.short_description = 'Contents'
  
  
  @admin.register(SiteConfiguration)
  class SiteConfigurationAdmin(SingletonModelAdmin):
      pass
  
  
  admin.site.unregister(Tag)
  
  
  class ProxyTag(Tag):
      class Meta:
          proxy = True
          verbose_name = 'tag'
  
  
  @admin.register(ProxyTag)
  class TagAdmin(admin.ModelAdmin):
      list_display = ["name", "slug"]
      ordering = ["name", "slug"]
      search_fields = ["name"]
      prepopulated_fields = {"slug": ["name"]}
  
  
  @admin.register(Answer)
  class AnswerAdmin(ExportActionModelAdmin, admin.ModelAdmin):
      list_display = ('__str__', 'card_section', 'observation')
      list_filter = (DateFilter,)
      resource_class = AnswerResource
  
      def get_export_formats(self):
          formats = (
              base_formats.CSV,
              base_formats.XLSX,
          )
          return [f for f in formats if f().can_export()]
  