import copy from django.contrib import admin from django.contrib.gis.admin import OSMGeoAdmin from .models import APClass, AP, Sighting, FieldNote from photos.forms import GalleryForm from utils.util import get_latlon from utils.widgets import CustomSelectMultiple, LGEntryForm from django.contrib.admin.options import FORMFIELD_FOR_DBFIELD_DEFAULTS class GalleryFormPlus(GalleryForm): def __init__(self, *args, **kwargs): super(GalleryFormPlus, self).__init__(*args, **kwargs) self.base_fields['seen_by'].widget = CustomSelectMultiple() class Meta: model = Sighting fields = '__all__' @admin.register(APClass) class APClassAdmin(admin.ModelAdmin): list_display = ('common_name', 'scientific_name', 'kind') list_filter = ('kind',) class SightingInline(OSMGeoAdmin, admin.StackedInline): """ This is very fragile and probably a bad idea since I copied this code straight from Django and it may change, but unless GeoDjango adds a Mixin, this will have to do. """ model = Sighting extra = 1 lat, lon = get_latlon() default_lon = lon default_lat = lat default_zoom = 13 units = True scrollable = False map_width = 700 map_height = 425 map_template = 'gis/admin/osm.html' openlayers_url = '/static/admin/js/OpenLayers.js' def __init__(self, parent_model, admin_site): self.admin_site = admin_site self.parent_model = parent_model self.opts = self.model._meta self.has_registered_model = admin_site.is_registered(self.model) overrides = copy.deepcopy(FORMFIELD_FOR_DBFIELD_DEFAULTS) for k, v in self.formfield_overrides.items(): overrides.setdefault(k, {}).update(v) self.formfield_overrides = overrides if self.verbose_name is None: self.verbose_name = self.model._meta.verbose_name if self.verbose_name_plural is None: self.verbose_name_plural = self.model._meta.verbose_name_plural @admin.register(AP) class APAdmin(admin.ModelAdmin): form = LGEntryForm inlines = [ SightingInline, ] list_display = ('common_name', 'have_seen', 'scientific_name', 'kind', 'code', 'apclass') list_filter = ('apclass__kind', 'apclass') search_fields = ['common_name', 'scientific_name'] def have_seen(self, obj): return obj.seen have_seen.admin_order_field = 'seen' have_seen.boolean = True class Media: js = ('image-loader.js', 'next-prev-links.js') @admin.register(Sighting) class SightingAdmin(OSMGeoAdmin): list_filter = (('location', admin.RelatedOnlyFieldListFilter),) list_display = ('ap', 'location') # options for OSM map Using custom ESRI topo map lat, lon = get_latlon() default_lon = lon default_lat = lat default_zoom = 13 units = True scrollable = False map_width = 700 map_height = 425 map_template = 'gis/admin/osm.html' openlayers_url = '/static/admin/js/OpenLayers.js' class Media: js = ('next-prev-links.js',) @admin.register(FieldNote) class FieldNoteAdmin(admin.ModelAdmin): form = LGEntryForm def get_form(self, request, obj=None, **kwargs): form = super(FieldNoteAdmin, self).get_form(request, obj, **kwargs) form.base_fields['sighting'].label_from_instance = lambda obj: "{} - {} - {}".format(obj.ap_common_name, obj.pub_date.strftime("%Y-%b-%d"), obj.location_name) return form list_display = ('pk', 'ap_common_name', 'sighting_pub_date', 'sighting_location') fieldsets = ( ('', { 'fields': ( 'sighting', 'body_markdown', ), 'classes': ( 'show', 'extrapretty', 'wide' ) } ), ) class Media: js = ('image-loader.js', 'next-prev-links.js') css = { "all": ("my_styles.css",) }