X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=planetstack%2Fcore%2Fadmin.py;h=460a4533b9537ccbefb2ce80bde2fa0076ed8ae1;hb=adae55f696049d0b6cf4f0ef7c5280d2e0dee2e0;hp=c173cb1bba5d76d3b446f8591b23553e3eecc145;hpb=86fd8a38d6ce40991b86c5378e2286ca2dc33420;p=plstackapi.git diff --git a/planetstack/core/admin.py b/planetstack/core/admin.py index c173cb1..460a453 100644 --- a/planetstack/core/admin.py +++ b/planetstack/core/admin.py @@ -234,6 +234,13 @@ class SliverInline(PlStackTabularInline): def formfield_for_foreignkey(self, db_field, request=None, **kwargs): if db_field.name == 'deploymentNetwork': kwargs['queryset'] = Deployment.select_by_acl(request.user) + # the inscrutable jquery selector below says: + # find the closest parent "tr" to the current element + # then find the child with class "field-node" + # then find the child with that is a select + # then return its id + kwargs['widget'] = forms.Select(attrs={'onChange': "update_nodes(this, $($(this).closest('tr')[0]).find('.field-node select')[0].id)"}) + #kwargs['widget'] = forms.Select(attrs={'onChange': "console.log($($($(this).closest('tr')[0]).children('.field-node')[0]).children('select')[0].id);"}) field = super(SliverInline, self).formfield_for_foreignkey(db_field, request, **kwargs) @@ -491,6 +498,14 @@ class DeploymentAdminForm(forms.ModelForm): verbose_name=('Sites'), is_stacked=False ) ) + images = forms.ModelMultipleChoiceField( + queryset=Image.objects.all(), + required=False, + help_text="Select which images should be deployed on this deployment", + widget=FilteredSelectMultiple( + verbose_name=('Images'), is_stacked=False + ) + ) class Meta: model = Deployment @@ -502,6 +517,42 @@ class DeploymentAdminForm(forms.ModelForm): if self.instance and self.instance.pk: self.fields['sites'].initial = [x.site for x in self.instance.sitedeployments_set.all()] + self.fields['images'].initial = [x.image for x in self.instance.imagedeployments_set.all()] + + def manipulate_m2m_objs(self, this_obj, selected_objs, all_relations, relation_class, local_attrname, foreign_attrname): + """ helper function for handling m2m relations from the MultipleChoiceField + + this_obj: the source object we want to link from + + selected_objs: a list of destination objects we want to link to + + all_relations: the full set of relations involving this_obj, including ones we don't want + + relation_class: the class that implements the relation from source to dest + + local_attrname: field name representing this_obj in relation_class + + foreign_attrname: field name representing selected_objs in relation_class + + This function will remove all newobjclass relations from this_obj + that are not contained in selected_objs, and add any relations that + are in selected_objs but don't exist in the data model yet. + """ + + existing_dest_objs = [] + for relation in list(all_relations): + if getattr(relation, foreign_attrname) not in selected_objs: + #print "deleting site", sdp.site + relation.delete() + else: + existing_dest_objs.append(getattr(relation, foreign_attrname)) + + for dest_obj in selected_objs: + if dest_obj not in existing_dest_objs: + #print "adding site", site + kwargs = {foreign_attrname: dest_obj, local_attrname: this_obj} + relation = relation_class(**kwargs) + relation.save() def save(self, commit=True): deployment = super(DeploymentAdminForm, self).save(commit=False) @@ -514,21 +565,8 @@ class DeploymentAdminForm(forms.ModelForm): # create/destroy the through models ourselves. There has to be # a better way... - sites = self.cleaned_data['sites'] - - existing_sites = [] - for sdp in list(deployment.sitedeployments_set.all()): - if sdp.site not in sites: - #print "deleting site", sdp.site - sdp.delete() - else: - existing_sites.append(sdp.site) - - for site in sites: - if site not in existing_sites: - #print "adding site", site - sdp = SiteDeployments(site=site, deployment=deployment) - sdp.save() + self.manipulate_m2m_objs(deployment, self.cleaned_data['sites'], deployment.sitedeployments_set.all(), SiteDeployments, "deployment", "site") + self.manipulate_m2m_objs(deployment, self.cleaned_data['images'], deployment.imagedeployments_set.all(), ImageDeployments, "deployment", "image") self.save_m2m() @@ -545,14 +583,14 @@ class SiteAssocInline(PlStackTabularInline): class DeploymentAdmin(PlanetStackBaseAdmin): model = Deployment - fieldList = ['name','sites', 'accessControl'] + fieldList = ['name','sites', 'images', 'accessControl'] fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-sites']})] - inlines = [DeploymentPrivilegeInline,NodeInline,TagInline,ImageDeploymentsInline] + inlines = [DeploymentPrivilegeInline,NodeInline,TagInline] # ,ImageDeploymentsInline] - user_readonly_inlines = [DeploymentPrivilegeROInline,NodeROInline,TagROInline,ImageDeploymentsROInline] + user_readonly_inlines = [DeploymentPrivilegeROInline,NodeROInline,TagROInline] # ,ImageDeploymentsROInline] user_readonly_fields = ['name'] - suit_form_tabs =(('sites','Deployment Details'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'),('imagedeployments','Images')) + suit_form_tabs =(('sites','Deployment Details'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags')) # ,('imagedeployments','Images')) def get_form(self, request, obj=None, **kwargs): if request.user.isReadOnlyUser(): @@ -729,6 +767,19 @@ class SliceAdmin(PlanetStackBaseAdmin): ('reservations','Reservations'), ) + def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None): + #deployment_nodes = {} + #for node in Node.objects.all(): + # deployment_nodes[node.deployment.id] = get(deployment_nodes, node.deployment.id, []).append( (node.id, node.name) ) + + deployment_nodes = [] + for node in Node.objects.all(): + deployment_nodes.append( (node.deployment.id, node.id, node.name) ) + + context["deployment_nodes"] = deployment_nodes + + return super(SliceAdmin, self).render_change_form(request, context, add, change, form_url, obj) + def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == 'site': kwargs['queryset'] = Site.select_by_user(request.user) @@ -775,14 +826,14 @@ class SlicePrivilegeAdmin(PlanetStackBaseAdmin): def save_model(self, request, obj, form, change): # update openstack connection to use this site/tenant auth = request.session.get('auth', {}) - auth['tenant'] = obj.slice.name + auth['tenant'] = obj.slice.slicename obj.os_manager = OpenStackManager(auth=auth, caller=request.user) obj.save() def delete_model(self, request, obj): # update openstack connection to use this site/tenant auth = request.session.get('auth', {}) - auth['tenant'] = obj.slice.name + auth['tenant'] = obj.slice.slicename obj.os_manager = OpenStackManager(auth=auth, caller=request.user) obj.delete() @@ -970,15 +1021,14 @@ class UserAdmin(UserAdmin): # These override the definitions on the base UserAdmin # that reference specific fields on auth.User. list_display = ('email', 'firstname', 'lastname', 'site', 'last_login') - #list_display = ('email', 'username','firstname', 'lastname', 'is_admin', 'last_login') list_filter = ('site',) inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline,UserDashboardViewInline] - fieldListLoginDetails = ['email','site','password','is_readonly','is_amin','public_key'] + fieldListLoginDetails = ['email','site','password','is_active','is_readonly','is_admin','public_key'] fieldListContactInfo = ['firstname','lastname','phone','timezone'] fieldsets = ( - ('Login Details', {'fields': ['email', 'site','password', 'is_readonly', 'is_admin', 'public_key'], 'classes':['suit-tab suit-tab-general']}), + ('Login Details', {'fields': ['email', 'site','password', 'is_active', 'is_readonly', 'is_admin', 'public_key'], 'classes':['suit-tab suit-tab-general']}), ('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}), #('Dashboard Views', {'fields': ('dashboards',), 'classes':['suit-tab suit-tab-dashboards']}), #('Important dates', {'fields': ('last_login',)}),