def get_link_context(self, context, obj, admin_site, querystring): """ Adds a `link` and `verbose_name` to the context, if :meth:`~adminlinks.templatetags.adminlinks_buttons.BaseAdminLink.is_valid` :param context: Hopefully, a :class:`~django.template.RequestContext` otherwise :meth:`~adminlinks.templatetags.adminlinks_buttons.BaseAdminLink.is_valid` is unlikely to be :data:`True` :param obj: the :class:`~django.db.models.Model` class to link to. Must have :class:`~django.db.models.Options` from which we can retrieve a :attr:`~django.db.models.Field.verbose_name` :param admin_site: name of the admin site to use; defaults to **"admin"** :param querystring: a querystring to include in the link output. Defaults to "_popup=1" :return: the link values. :rtype: dictionary. """ return _add_link_to_context(admin_site, context['request'], obj._meta, 'add', None, query=querystring)
def maybe_fix_redirection(self, request, response, obj=None): """ This is basically a middleware for admin responses from add/edit screens. Inspect's a URL, and adds in our required fields if they're not there. eg: if a URL has no querystring, or the querystring does not contain `content_id`, `content_type` and `region` it will attempt to insert them, and if `_autoclose` was in the requesting URL, it should be maintained. """ resp = super(ChunkAdmin, self).maybe_fix_redirection(request, response, obj) return_early = ( not resp.has_header('location'), not hasattr(resp, 'redirect_parts'), hasattr(resp, 'canonical'), # something wants to be *final* obj is None, ) if any(return_early): resp['X-Chunkadmin-Response'] = 'early' return resp # get the modeladmin in question, from the URL provided. func = resolve(resp.redirect_parts[2]).func # python 3 if hasattr(func, '__closure__'): func = func.__closure__ else: # python 2 func = func.func_closure func = func[0].cell_contents # it doesn't look like a chunk admin, so we can't know we need to # redirect back to the parent. if (not hasattr(func, 'response_max') and not hasattr(func, 'render_into_region')): resp['X-Chunkadmin-Response'] = 'not-chunkadmin' return resp # set up reasons to go back to the parent object's edit view. redirect_to_parent_if = ( not self.wants_to_autoclose(request), not self.wants_to_continue_editing(request) ) # we don't want to autoclose, and we don't want to save a new # or add another, so we're hopefully inside a bare add/change view # so we probably ought to go back to the parent object's edit view. if all(redirect_to_parent_if): abuse_adminlink = _add_link_to_context( admin_site=self.admin_site.name, request=request, opts=obj.content_object._meta, permname='change', url_params=[obj.content_id], query=resp.redirect_parts[3]) resp.redirect_parts = list(urlsplit(abuse_adminlink['link'])) resp['Location'] = urlunsplit(resp.redirect_parts) resp['X-Chunkadmin-Response'] = 'redirect-to-parent' return resp # we either wanted to autoclose, or we wanted to continue/add another # etc, so we don't want to redirect elsewhere, we just want to # update the querystring with fields required by the ChunkAdmin querystring = QueryDict(resp.redirect_parts[3], mutable=True) # delete any values which could be wrong [but shouldn't be!] for x in (REQUEST_VAR_REGION, REQUEST_VAR_CT, REQUEST_VAR_ID): if x in querystring: del querystring[x] querystring.update({REQUEST_VAR_ID: obj.content_id, REQUEST_VAR_CT: obj.content_type_id, REQUEST_VAR_REGION: obj.region}) resp.redirect_parts[3] = querystring.urlencode() resp['Location'] = urlunsplit(resp.redirect_parts) resp['X-Chunkadmin-Response'] = 'autoclose' return resp