Per creare moduli di amministrazione personalizzati abbiamo definito una nuova classe che può essere utilizzata come mixin.L'approccio è abbastanza flessibile:
ModelAdmin: definire un fieldset contenente tutti campi
ModelForm: restringono i campi essendo mostrati
FlexibleModelAdmin: override get_fieldsets-metodo di ModelAdmin; restituisce un fieldset ridotta che contiene solo i campi definiti nella forma di amministrazione
class FlexibleModelAdmin(object):
'''
adds the possibility to use a fieldset as template for the generated form
this class should be used as mix-in
'''
def _filterFieldset(self, proposed, form):
'''
remove fields from a fieldset that do not
occur in form itself.
'''
allnewfields = []
fields = form.base_fields.keys()
fieldset = []
for fsname, fdict in proposed:
newfields = []
for field in fdict.get('fields'):
if field in fields:
newfields.append(field)
allnewfields.extend(newfields)
if newfields:
newentry = {'fields': newfields}
fieldset.append([fsname, newentry])
# nice solution but sets are not ordered ;)
# don't forget fields that are in a form but were forgotten
# in fieldset template
lostfields = list(set(fields).difference(allnewfields))
if len(lostfields):
fieldset.append(['lost in space', {'fields': lostfields}])
return fieldset
def get_fieldsets(self, request, obj=None):
'''
Hook for specifying fieldsets for the add form.
'''
if hasattr(self, 'fieldsets_proposed'):
form = self.get_form(request, obj)
return self._filterFieldset(self.fieldsets_proposed, form)
else:
return super(FlexibleModelAdmin, self).get_fieldsets(request, obj)
Nel modello di amministrazione si definisce fieldsets_proposed che serve da modello e contiene tutti i campi.
class ReservationAdmin(FlexibleModelAdmin, admin.ModelAdmin):
list_display = ['id', 'displayFullName']
list_display_links = ['id', 'displayFullName']
date_hierarchy = 'reservation_start'
ordering = ['-reservation_start', 'vehicle']
exclude = ['last_modified_by']
# considered by FlexibleModelAdmin as template
fieldsets_proposed = (
(_('General'), {
'fields': ('vehicle', 'reservation_start', 'reservation_end', 'purpose') # 'added_by'
}),
(_('Report'), {
'fields': ('mileage')
}),
(_('Status'), {
'fields': ('active', 'editable')
}),
(_('Notes'), {
'fields': ('note')
}),
)
....
def get_form(self, request, obj=None, **kwargs):
'''
set the form depending on the role of the user for the particular group
'''
if request.user.is_superuser:
self.form = ReservationAdminForm
else:
self.form = ReservationUserForm
return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
admin.site.register(Reservation, ReservationAdmin)
nel modello costituisce ora è possibile definire i campi che devono essere esclusi/inclusi. get_fieldset() della classe mixin si assicura che vengano restituiti solo i campi definiti nel modulo.
class ReservationAdminForm(ModelForm):
class Meta:
model = Reservation
exclude = ('added_by', 'last_modified_by')
class ReservationUserForm(BaseReservationForm):
class Meta:
model = Reservation
fields = ('vehicle', 'reservation_start', 'reservation_end', 'purpose', 'note')
Hai provato a dichiarare un fieldset da qualche parte nella classe PageOptions solo per vedere se funziona? –
Sì, lo spettacolo è attivo, non importa cosa c'è in get_form –