Skip to content

Commit c12ecad

Browse files
committed
building out admin forms
1 parent de326f7 commit c12ecad

6 files changed

Lines changed: 389 additions & 18 deletions

File tree

layers/admin.py

Lines changed: 197 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,204 @@
44

55
# Register your models here.
66

7-
# class ThemeAdmin(admin.ModelAdmin):
8-
# list_display = ('display_name', 'name', 'order', 'primary_site', 'preview_site')
7+
class ThemeAdminForm(forms.ModelForm):
8+
class Meta:
9+
model = Theme
10+
exclude = ('layer_type', "slug_name")
911

10-
# def formfield_for_manytomany(self, db_field, request=None, **kwargs):
11-
# if db_field.name == 'site':
12-
# kwargs['widget'] = forms.CheckboxSelectMultiple()
13-
# kwargs['widget'].attrs['style'] = 'list-style-type: none;'
14-
# kwargs['widget'].can_add_related = False
12+
class ThemeAdmin(admin.ModelAdmin):
13+
list_display = ('display_name', 'name', 'order', 'primary_site', 'preview_site')
14+
form = ThemeAdminForm
15+
def get_queryset(self, request):
16+
# use our manager, rather than the default one
17+
qs = self.model.all_objects.get_queryset()
1518

16-
# return db_field.formfield(**kwargs)
19+
# we need this from the superclass method
20+
ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)
21+
if ordering:
22+
qs = qs.order_by(*ordering)
23+
return qs
24+
def formfield_for_manytomany(self, db_field, request=None, **kwargs):
25+
if db_field.name == 'site':
26+
kwargs['widget'] = forms.CheckboxSelectMultiple()
27+
kwargs['widget'].attrs['style'] = 'list-style-type: none;'
28+
kwargs['widget'].can_add_related = False
29+
30+
return db_field.formfield(**kwargs)
31+
class ThemeChoiceField(forms.ModelMultipleChoiceField):
32+
def label_from_instance(self, obj):
33+
# Return the name of the Theme object to be used as the label for the choice
34+
return obj.name
35+
36+
class SublayerChoiceField(forms.ModelMultipleChoiceField):
37+
def label_from_instance(self, obj):
38+
# Return the name of the Theme object to be used as the label for the choice
39+
return obj.name
40+
41+
class CompanionLayerChoiceField(forms.ModelMultipleChoiceField):
42+
def label_from_instance(self, obj):
43+
# Return the name of the Theme object to be used as the label for the choice
44+
return obj.name
45+
46+
47+
48+
class LayerForm(forms.ModelForm):
49+
order = forms.IntegerField(required=False)
50+
themes = ThemeChoiceField(queryset=Theme.all_objects.all().filter(layer_type=''), required=False, widget = admin.widgets.FilteredSelectMultiple('themes', False))
51+
is_sublayer = forms.BooleanField(required=False)
52+
has_companion = forms.BooleanField(required=False)
53+
sublayers = SublayerChoiceField(queryset=Layer.all_objects.all(), required=False, widget = admin.widgets.FilteredSelectMultiple('sublayers', False))
54+
companion_layers = CompanionLayerChoiceField(queryset=Layer.all_objects.all(), required=False, widget = admin.widgets.FilteredSelectMultiple('companion layers', False))
55+
class Meta:
56+
exclude = ('slug_name',)
57+
model = Layer
58+
fields = '__all__'
59+
widgets = {
60+
61+
'attribute_fields': admin.widgets.FilteredSelectMultiple('Attribute fields', False),
62+
'lookup_table': admin.widgets.FilteredSelectMultiple('Lookup table', False),
63+
}
64+
65+
66+
def save(self, commit=True):
67+
# Save the Layer instance first
68+
layer = super().save(commit=commit)
69+
70+
# Now save or update the related ChildOrder instance or other related data
71+
# This is simplified; you'd likely need more logic here
72+
ChildOrder.objects.update_or_create(
73+
content_object=layer,
74+
defaults={'order': self.cleaned_data['order']}
75+
)
76+
# Handle other fields similarly
77+
78+
return layer
79+
class LayerArcRESTForm(LayerForm):
80+
class Meta:
81+
model = LayerArcREST
82+
fields = ['arcgis_layers', 'password_protected', 'query_by_point', 'disable_arcgis_attributes']
83+
class LayerAdmin(admin.ModelAdmin):
84+
def get_parent_theme(self, obj):
85+
# Fetch the ContentType for the Layer model
86+
content_type = ContentType.objects.get_for_model(obj)
87+
88+
# Try to fetch the corresponding ChildOrder for this Layer
89+
child_order = ChildOrder.objects.filter(content_type=content_type, object_id=obj.pk).first()
90+
91+
# Return the name of the parent theme if exists
92+
return child_order.parent_theme.name if child_order and child_order.parent_theme else 'None'
93+
get_parent_theme.short_description = 'Theme' # Sets column name
94+
95+
def get_order(self, obj):
96+
# Fetch the ContentType for the Layer model
97+
content_type = ContentType.objects.get_for_model(obj)
98+
99+
# Try to fetch the corresponding ChildOrder for this Layer
100+
child_order = ChildOrder.objects.filter(content_type=content_type, object_id=obj.pk).first()
101+
102+
# Return the order if exists
103+
return child_order.order if child_order else 'None'
104+
get_order.short_description = 'Order' # Sets column name
105+
106+
def get_form(self, request, obj=None, **kwargs):
107+
# Dynamically set the form class based on the layer_type
108+
if obj and obj.layer_type == 'ArcRest':
109+
kwargs['form'] = LayerArcRESTForm
110+
else:
111+
kwargs['form'] = LayerForm
112+
return super().get_form(request, obj, **kwargs)
113+
114+
def get_fieldsets(self, request, obj=None):
115+
# Dynamically return fieldsets based on the layer_type
116+
if obj and obj.layer_type == 'ArcRest':
117+
# No need to modify self.fieldsets; directly return the combined fieldsets
118+
return self.base_fieldsets + self.arcrest_fieldsets
119+
return self.base_fieldsets
120+
list_display = ('name', 'layer_type', 'date_modified', "get_parent_theme", "get_order", 'data_publish_date', 'data_source')
121+
search_fields = ['name', 'layer_type', 'date_modified', 'url', 'data_source']
122+
ordering = ('name', )
123+
exclude = ('slug_name',)
124+
class Media:
125+
js = ['layer_admin.js',]
126+
127+
if settings.CATALOG_TECHNOLOGY not in ['default', None]:
128+
# catalog_fields = ('catalog_name', 'catalog_id',)
129+
# catalog_fields = 'catalog_name'
130+
basic_fields = (
131+
'catalog_name',
132+
('name','layer_type',),
133+
('url', 'proxy_url'),
134+
'site'
135+
)
136+
else:
137+
basic_fields = (
138+
('name','layer_type',),
139+
('url', 'proxy_url'),
140+
'site'
141+
)
142+
base_fieldsets = (
143+
('BASIC INFO', {
144+
'fields': basic_fields
145+
}),
146+
('LAYER ORGANIZATION', {
147+
# 'classes': ('collapse', 'open',),
148+
'fields': (
149+
('order','themes'),
150+
('is_sublayer','sublayers'),
151+
('has_companion','companion_layers'),
152+
# RDH 2019-10-25: We don't use this, and it doesn't seem helpful
153+
# ('is_disabled','disabled_message')
154+
)
155+
}),
156+
('METADATA', {
157+
'classes': ('collapse',),
158+
'fields': (
159+
'description', 'overview','data_source','data_notes', 'data_publish_date'
160+
)
161+
}),
162+
('LEGEND', {
163+
'classes': ('collapse',),
164+
'fields': (
165+
'show_legend',
166+
'legend',
167+
('legend_title','legend_subtitle')
168+
)
169+
}),
170+
('LINKS', {
171+
'classes': ('collapse',),
172+
'fields': (
173+
('metadata','source'),
174+
('bookmark', 'kml'),
175+
('data_download','learn_more'),
176+
('map_tiles'),
177+
)
178+
}),
179+
('SHARING', {
180+
'classes': ('collapse',),
181+
'fields': (
182+
'shareable_url',
183+
)
184+
}),)
185+
arcrest_fieldsets = (
186+
('ArcGIS DETAILS', {
187+
'classes': ('collapse',),
188+
'fields': (
189+
('arcgis_layers', 'password_protected', 'query_by_point', 'disable_arcgis_attributes'),
190+
)
191+
}),
192+
)
193+
194+
def get_queryset(self, request):
195+
# use our manager, rather than the default one
196+
qs = self.model.all_objects.get_queryset()
197+
198+
# we need this from the superclass method
199+
ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)
200+
if ordering:
201+
qs = qs.order_by(*ordering)
202+
return qs
17203

18204
# if hasattr(settings, 'DATA_MANAGER_ADMIN'):
19-
# admin.site.register(Theme, ThemeAdmin)
205+
# admin.site.register(Theme, ThemeAdmin)
206+
admin.site.register(Theme, ThemeAdmin)
207+
admin.site.register(Layer, LayerAdmin)

layers/migrations/0002_auto_20240206_2047.py renamed to layers/migrations/0002_auto_20240207_1925.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
# Generated by Django 3.2.23 on 2024-02-06 20:47
1+
# Generated by Django 3.2.23 on 2024-02-07 19:25
22

33
import colorfield.fields
4+
import django.contrib.sites.managers
45
from django.db import migrations, models
56
import django.db.models.deletion
67
import django.utils.timezone
8+
import layers.models
79
import uuid
810

911

1012
class Migration(migrations.Migration):
1113

1214
dependencies = [
15+
('sites', '0002_alter_domain_unique'),
1316
('contenttypes', '0002_remove_content_type_name'),
1417
('layers', '0001_initial'),
1518
]
@@ -49,6 +52,10 @@ class Migration(migrations.Migration):
4952
'abstract': False,
5053
},
5154
bases=('layers.layer',),
55+
managers=[
56+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
57+
('all_objects', layers.models.AllObjectsManager()),
58+
],
5259
),
5360
migrations.CreateModel(
5461
name='LayerArcREST',
@@ -63,6 +70,10 @@ class Migration(migrations.Migration):
6370
'abstract': False,
6471
},
6572
bases=('layers.layer',),
73+
managers=[
74+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
75+
('all_objects', layers.models.AllObjectsManager()),
76+
],
6677
),
6778
migrations.CreateModel(
6879
name='LayerVector',
@@ -83,6 +94,10 @@ class Migration(migrations.Migration):
8394
'abstract': False,
8495
},
8596
bases=('layers.layer',),
97+
managers=[
98+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
99+
('all_objects', layers.models.AllObjectsManager()),
100+
],
86101
),
87102
migrations.CreateModel(
88103
name='LayerWMS',
@@ -105,6 +120,10 @@ class Migration(migrations.Migration):
105120
'abstract': False,
106121
},
107122
bases=('layers.layer',),
123+
managers=[
124+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
125+
('all_objects', layers.models.AllObjectsManager()),
126+
],
108127
),
109128
migrations.CreateModel(
110129
name='LayerXYZ',
@@ -116,6 +135,10 @@ class Migration(migrations.Migration):
116135
'abstract': False,
117136
},
118137
bases=('layers.layer',),
138+
managers=[
139+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
140+
('all_objects', layers.models.AllObjectsManager()),
141+
],
119142
),
120143
migrations.CreateModel(
121144
name='Library',
@@ -124,6 +147,10 @@ class Migration(migrations.Migration):
124147
('queryable', models.BooleanField(default=False, help_text='Select when layers are queryable - e.g. MDAT and CAS')),
125148
],
126149
bases=('layers.layer',),
150+
managers=[
151+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
152+
('all_objects', layers.models.AllObjectsManager()),
153+
],
127154
),
128155
migrations.CreateModel(
129156
name='LookupInfo',
@@ -168,6 +195,20 @@ class Migration(migrations.Migration):
168195
name='theme',
169196
options={'ordering': ['order']},
170197
),
198+
migrations.AlterModelManagers(
199+
name='layer',
200+
managers=[
201+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
202+
('all_objects', layers.models.AllObjectsManager()),
203+
],
204+
),
205+
migrations.AlterModelManagers(
206+
name='theme',
207+
managers=[
208+
('objects', django.contrib.sites.managers.CurrentSiteManager('site')),
209+
('all_objects', layers.models.AllObjectsManager()),
210+
],
211+
),
171212
migrations.AddField(
172213
model_name='layer',
173214
name='annotated',
@@ -350,6 +391,11 @@ class Migration(migrations.Migration):
350391
name='show_legend',
351392
field=models.BooleanField(default=True, help_text='show the legend for this layer if available'),
352393
),
394+
migrations.AddField(
395+
model_name='layer',
396+
name='site',
397+
field=models.ManyToManyField(related_name='layer_site', to='sites.Site'),
398+
),
353399
migrations.AddField(
354400
model_name='layer',
355401
name='slug_name',
@@ -428,6 +474,11 @@ class Migration(migrations.Migration):
428474
name='overview',
429475
field=models.TextField(blank=True, default='', null=True),
430476
),
477+
migrations.AddField(
478+
model_name='theme',
479+
name='site',
480+
field=models.ManyToManyField(related_name='theme_site', to='sites.Site'),
481+
),
431482
migrations.AddField(
432483
model_name='theme',
433484
name='slug_name',

0 commit comments

Comments
 (0)