コード例 #1
0
    def get_formset(self, request, obj=None, **kwargs):
        # sidestep validation which wants to inherit from BaseModelFormSet
        self.formset = EditRegionInlineFormSet
        fset = super(EditRegionInline, self).get_formset(request, obj,
                                                         **kwargs)
        modeladmin = get_modeladmin(EditRegionChunk, self.admin_site.name)
        if obj is not None and request.method == 'POST':
            # As I won't remember why we have to do this, later, this is the
            # traceback which not doing it caused:
            # https://gist.github.com/kezabelle/40653a0ad1ffd8fc77ba
            # Basically, the template gets changed half way through the request
            # because of the different points at which objects are saved.
            # By not relying on the new instance (with the changed template)
            # instead using the one in the DB (with the old template) we can
            # ensure the regions line up correctly.
            logger.info('Editing an %(obj)r; we may be changing the region '
                        'group being used, so re-grabbing the DB version')
            obj = obj.__class__.objects.get(pk=obj.pk)
        fset.region_changelists = modeladmin.get_changelists_for_object(
            request=request, obj=obj, config=None)
        fset.editregion_config = get_configuration(obj=obj)

        # this bind is necessary for the template to emit dynamic
        # template changes.
        fset.editregions_template_fieldname = getattr(
            get_modeladmin(obj), 'editregions_template_field', None)
        return fset
コード例 #2
0
    def test_continue_editing_parent_object(self):
        """
        if continue editing is hit, it should go back to the parent URL,
        I think?
        """
        user = User(username='******', is_staff=True, is_superuser=True,
                    is_active=True)
        user.set_password('test')
        user.full_clean()
        user.save()
        admin_instance = get_modeladmin(Iframe)
        self.assertIsInstance(admin_instance, RealishAdmin)

        request = RequestFactory().get('/', {
            '_continue': 1,
        })
        request.user = user
        iframe_admin = reverse('admin:embeds_iframe_add')
        response_301 = HttpResponsePermanentRedirect(redirect_to=iframe_admin)

        ct = get_content_type(User)
        iframe = Iframe(position=2, region='test', content_type=ct,
                        content_id=user.pk, url='https://news.bbc.co.uk/')
        iframe.full_clean()
        iframe.save()

        new_response = admin_instance.maybe_fix_redirection(
            request=request, response=response_301, obj=iframe)
        self.assertEqual(new_response['X-Chunkadmin-Response'],
                         'redirect-to-parent')

        self.assertEqual(301, new_response.status_code)
        self.assertEqual('/admin_mountpoint/auth/user/1/?_data_changed=1',
                         new_response['Location'])
コード例 #3
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_render_into_region(self):
     theadmin = get_modeladmin(self.file)
     out = theadmin.render_into_region(obj=self.file, context=Context({
         'chunkloop': {'object': self.file}
     }))
     self.assertIn('a href="x/y/z.gif?t=', out)
     self.assertIn('>x</a>', out)
コード例 #4
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_render_into_region(self):
     theadmin = get_modeladmin(self.model)
     obj = self.model(local='x/y')
     context = Context()
     # nothing is output now, because we want to
     # render_into_mediagroup instead
     self.assertIsNone(theadmin.render_into_region(obj=obj, context=context))
コード例 #5
0
    def _test_view(self, func='add_view', generate_chunks=1):
        user = User(username='******', is_staff=True, is_superuser=True,
                    is_active=True)
        user.set_password('test')
        user.full_clean()
        user.save()
        ct = get_content_type(User)
        request = RequestFactory().get('/', {
            REQUEST_VAR_CT: ct.pk,
            REQUEST_VAR_ID: user.pk,
            REQUEST_VAR_REGION: 'test'
        })
        request.user = user
        admin_instance = get_modeladmin(Iframe)

        for x in range(0, generate_chunks):
            iframe = Iframe(position=2, region='test', content_type=ct,
                            content_id=user.pk, url='https://news.bbc.co.uk/')
            iframe.full_clean()
            iframe.save()

        kwargs = {'request': request}
        if func != 'add_view':
            kwargs.update({'object_id': force_text(iframe.pk)})
        view = getattr(admin_instance, func)
        view(**kwargs)

        # now do the view again without the fields required by the decorator
        request = RequestFactory().get('/')
        request.user = user
        kwargs.update({'request': request})
        with self.assertRaises(SuspiciousOperation):
            view(**kwargs)
コード例 #6
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_render_into_summary(self):
     theadmin = get_modeladmin(self.model)
     obj = self.model()
     obj.url = """<rss version="2.0">
     <channel>
     <title>Sample Feed</title>
     </channel>
     </rss>"""
     self.assertEqual(theadmin.render_into_summary(obj=obj, context={}),
                      'Sample Feed')
コード例 #7
0
 def test_leave_unchanged(self):
     request = RequestFactory().get('/')
     response_200 = HttpResponse(content='ok')
     admin_instance = get_modeladmin(Iframe)
     new_response = admin_instance.maybe_fix_redirection(
         request=request, response=response_200)
     # returned unchanged
     self.assertEqual(new_response['X-Chunkadmin-Response'], 'early')
     self.assertEqual(force_text('ok'), force_text(new_response.content))
     self.assertEqual(200, new_response.status_code)
コード例 #8
0
 def configure(self, obj):
     self.obj = obj
     self.ct = get_content_type(obj)
     modeladmin = get_modeladmin(self.obj)
     if hasattr(modeladmin, 'get_editregions_template_choices'):
         self.valid_templates = modeladmin.get_editregions_template_choices(
             obj=self.obj)
     possible_templates = modeladmin.get_editregions_templates(
         obj=self.obj)
     self.set_template(possible_templates)
コード例 #9
0
    def get_changelists_for_object(self, request, obj, **kwargs):
        changelists = []

        if obj is not None:
            logger.debug('Editing `{obj!r}`, so do '
                         '`get_changelists_for_object`'.format(obj=obj))

            attach_configuration(obj, EditRegionConfiguration)
            config = get_configuration(obj)

            # Dynamic template changes ...
            obj_admin = get_modeladmin(admin_namespace=self.admin_site.name,
                                       obj=obj)
            if hasattr(obj_admin, 'editregions_template_field'):
                fieldname = obj_admin.editregions_template_field
                template_name = request.GET.get(fieldname, None)
                kv = TemplateRequestKeyValue(key=fieldname, value=template_name)
                if config.is_valid_template(template_name):
                    logger.debug("{kv!r} was valid for this {obj!r} "
                                 "and {modeladmin!r}".format(
                                     kv=kv, obj=obj, modeladmin=obj_admin))
                    config.set_template(template_name)

            # store the old get here, because it gets changed inside the region
            # loops, which is a lossy process.
            old_get = request.GET
            # mutate the querystring and set some data onto it, which will
            # be passed to the get_changelist_filters method, as well as
            # being used to filter the ChangeList correctly.
            # new_get = request.GET.copy()
            new_get = QueryDict('', mutable=True)
            new_get[REQUEST_VAR_CT] = get_content_type(obj).pk
            new_get[REQUEST_VAR_ID] = obj.pk

            for region in config.config:
                new_get[REQUEST_VAR_REGION] = region
                request.GET = new_get
                our_list_display = self.list_display[:]
                our_list_links = self.get_list_display_links(
                    request=request, list_display=our_list_display)
                ChangeList = self.get_changelist(request, **kwargs)
                cl = ChangeList(request=request, model=self.model,
                                list_display=our_list_display,
                                list_display_links=our_list_links,
                                list_filter=self.list_filter,
                                date_hierarchy=None, search_fields=None,
                                list_select_related=None, list_per_page=100,
                                list_max_show_all=100, list_editable=None,
                                model_admin=self, parent_obj=obj,
                                parent_conf=config)
                changelists.append(cl)
            # as the internal request.GET may be lossy, we restore the original
            # data here.
            request.GET = old_get
        return changelists
コード例 #10
0
 def get_response_add_context(self, request, obj):
     """
     Override the default contexts generated by AdminlinksMixin to add our
     HTML.
     """
     modeladmin = get_modeladmin(EditRegionChunk, self.admin_site.name)
     changelists = modeladmin.render_changelists_for_object(
         request=request, obj=obj.content_object)
     context = super(ChunkAdmin, self).get_response_add_context(request, obj)
     context.update(html=changelists)
     return context
コード例 #11
0
 def setUp(self):
     try:
         admin.site.unregister(EditRegionChunk)
     except NotRegistered:
         pass
     admin.site.register(EditRegionChunk, EditRegionAdmin)
     self.admin = get_modeladmin(EditRegionChunk)
     try:
         admin.site.unregister(Iframe)
     except NotRegistered:
         pass
     admin.site.register(Iframe, IframeAdmin)
コード例 #12
0
def render_one_mediagroup(context, chunk, extra, renderer=None):
    # we could just let the errors bubble up, but instead we'll provide more
    # helpful error messages than one might otherwise get (AttributeError for
    # no render_into_region, TypeError for calling render_into_region because of
    # it being unbound method (got RequestContext instance instead))
    if renderer is None:
        logger.debug('No renderer given as an argument, fetching the '
                     'ModelAdmin instance for the first time')
        renderer = get_modeladmin(chunk)
    if hasattr(renderer, 'render_into_mediagroup'):
        return renderer.render_into_mediagroup(context=context, obj=chunk,
                                               extra=extra)
    return None
コード例 #13
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_render_into_region(self):
     theadmin = get_modeladmin(self.model)
     obj = self.model(content='var x;')
     # fake the iteration context
     context = Context({
         'chunkloop': {
             'object': obj,
         }
     })
     # nothing is output now, because we want to
     # render_into_mediagroup instead
     result = theadmin.render_into_region(obj=obj, context=context)
     self.assertIsNone(result)
コード例 #14
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def setUp(self):
     sample_user, created = User.objects.get_or_create(username='******')
     user_ct = get_content_type(sample_user)
     sr = SearchResults(position=1, content_type=user_ct,
                        content_id=sample_user.pk, region='test',
                        connection='default', query="goose fat")
     sr.full_clean()
     try:
         admin.site.unregister(SearchResults)
     except NotRegistered:
         pass
     admin.site.register(SearchResults, SearchResultsAdmin)
     self.modeladmin = get_modeladmin(SearchResults)
     self.obj = sr
コード例 #15
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def setUp(self):
     sample_user, created = User.objects.get_or_create(username='******')
     user_ct = get_content_type(sample_user)
     mlt = MoreLikeThis(position=1, content_type=user_ct,
                        content_id=sample_user.pk, region='test',
                        connection='default')
     mlt.full_clean()
     try:
         admin.site.unregister(MoreLikeThis)
     except NotRegistered:
         pass
     admin.site.register(MoreLikeThis, MoreLikeThisAdmin)
     self.modeladmin = get_modeladmin(MoreLikeThis)
     self.obj = mlt
コード例 #16
0
 def test_returned_data_changed(self):
     """
     Just check that the `_data_changed` parameter is added the response.
     """
     request = RequestFactory().get('/')
     admin_instance = get_modeladmin(Iframe)
     response_302 = HttpResponseRedirect(redirect_to='/admin_mountpoint/')
     new_response = admin_instance.maybe_fix_redirection(
         request=request, response=response_302)
     # returned early because it was a redirect, but we updated the
     # querystring anyway
     self.assertEqual(new_response['X-Chunkadmin-Response'], 'early')
     self.assertEqual(302, new_response.status_code)
     self.assertEqual('/admin_mountpoint/?_data_changed=1',
                      new_response['Location'])
コード例 #17
0
def render_one_chunk(context, chunk, extra, renderer=None):
    # we could just let the errors bubble up, but instead we'll provide more
    # helpful error messages than one might otherwise get (AttributeError for
    # no render_into_region, TypeError for calling render_into_region because of
    # it being unbound method (got RequestContext instance instead))
    if renderer is None:
        logger.debug('No renderer given as an argument, fetching the '
                     'ModelAdmin instance for the first time')
        renderer = get_modeladmin(chunk)
    if not hasattr(renderer, 'render_into_region'):
        msg = ('{0.__class__!r} does not have a `render_into_region` '
               'method'.format(renderer))
        raise ImproperlyConfigured(msg)
    return renderer.render_into_region(context=context, obj=chunk,
                                       extra=extra)
コード例 #18
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_save_model(self):
     theadmin = get_modeladmin(self.model)
     obj = self.model(position=1)
     obj.url = """<rss version="2.0">
     <channel>
     <title>Sample Feed</title>
     </channel>
     </rss>"""
     request = RequestFactory().get('/', data={
         REQUEST_VAR_CT: 1,
         REQUEST_VAR_ID: 1,
         REQUEST_VAR_REGION: 'test'
     })
     theadmin.save_model(request=request, obj=obj, form=Form(),
                         change=False)
コード例 #19
0
    def get_object_tools(self, obj):
        """
        Show the modifiers for this object. Currently just implements the
        drag handle as per `django-treeadmin`_.

        :return: the list of actions or tools available for this object
        :rtype: string
        """
        modeladmin = get_modeladmin(obj)
        if hasattr(modeladmin, 'get_editregions_subclass_tools'):
            value = modeladmin.get_editregions_subclass_tools(obj=obj)
        else:
            value = ''
        return '<div class="chunk-object-tools">{value!s}</div>'.format(
            value=value)
コード例 #20
0
    def test_logging(self):
        user = User(username='******')
        user.set_password('test')
        user.full_clean()
        user.save()
        ct = get_content_type(User)
        iframe = Iframe(position=2, region='test', content_type=ct,
                        content_id=user.pk, url='https://news.bbc.co.uk/')
        iframe.full_clean()
        iframe.save()
        request = RequestFactory().get('/')
        request.user = user
        admin_instance = get_modeladmin(Iframe)

        admin_instance.log_addition(request, iframe)
        admin_instance.log_change(request, iframe, "we changed a thing!")
        admin_instance.log_deletion(request, iframe, "we deleted a thing!")

        # find them on the user
        logs = LogEntry.objects.get(content_type=ct, object_id=user.pk,
                                    user=user, action_flag=ADDITION)
        self.assertEqual(force_text(logs), 'Added "test".')
        logs = LogEntry.objects.get(content_type=ct, object_id=user.pk,
                                    user=user, action_flag=CHANGE)
        self.assertEqual(force_text(logs), 'Changed "test" - we changed a '
                                           'thing!')
        # can't check for deletions properly, see
        # https://code.djangoproject.com/ticket/21771#ticket

        # logs = LogEntry.objects.get(content_type=ct, object_id=user.pk,
        #                             user=user, action_flag=DELETION)
        # self.assertEqual(force_text(logs), 'Changed "test" - we changed a '
        #                                    'thing!')

        # find them on the iframe
        ct = get_content_type(Iframe)
        logs = LogEntry.objects.get(content_type=ct, object_id=iframe.pk,
                                    user=user, action_flag=ADDITION)
        self.assertEqual(force_text(logs), 'Added "https://news.bbc.co.uk/".')
        logs = LogEntry.objects.get(content_type=ct, object_id=iframe.pk,
                                    user=user, action_flag=CHANGE)
        self.assertEqual(force_text(logs), 'Changed "https://news.bbc.co.uk/" '
                                           '- we changed a thing!')
        # can't check for deletions properly, see
        # https://code.djangoproject.com/ticket/21771#ticket
        logs = LogEntry.objects.filter(content_type=ct, object_id=user.pk,
                                       user=user, action_flag=DELETION)
        self.assertEqual(force_text(logs[0]), 'Deleted "we deleted a thing!."')
コード例 #21
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_render_into_region(self):
     theadmin = get_modeladmin(self.model)
     obj = self.model()
     # fake the url into a string parse.
     obj.url = """<rss version="2.0">
     <channel>
     <title>Sample Feed</title>
     </channel>
     </rss>"""
     # fake the iteration context
     context = Context({
         'chunkloop': {
             'object': obj,
         }
     })
     self.assertIn('<span>Sample Feed</span>',
                   theadmin.render_into_region(obj=obj, context=context))
コード例 #22
0
 def get_response_delete_context(self, request, obj_id, extra_context):
     """
     Override the default contexts generated by AdminlinksMixin to add our
     HTML.
     """
     modeladmin = get_modeladmin(EditRegionChunk, self.admin_site.name)
     context = super(ChunkAdmin, self).get_response_delete_context(
         request, obj_id, extra_context)
     try:
         changelists = modeladmin.render_changelists_for_object(
             request=request, obj=extra_context['gfk']['content_object'])
         context.update(html=changelists)
     except KeyError as e:
         # extra context didn't include gfk, or possibly content_object within
         # that gfk key, either way, we now can't render the HTML for the
         # client :(
         pass
     return context
コード例 #23
0
 def test_to_other_url(self):
     """
     Going to a non-chunkadmin URL should be ok, and should also put the
     `_data_changed` parameter onto the URL.
     """
     user = User(username='******', is_staff=True, is_superuser=True,
                 is_active=True)
     user.set_password('test')
     user.full_clean()
     user.save()
     request = RequestFactory().get('/')
     response_302 = HttpResponseRedirect(redirect_to='/admin_mountpoint/')
     admin_instance = get_modeladmin(Iframe)
     new_response = admin_instance.maybe_fix_redirection(
         request=request, response=response_302, obj=user)
     self.assertEqual(new_response['X-Chunkadmin-Response'], 'not-chunkadmin')  # noqa
     self.assertEqual(302, new_response.status_code)
     self.assertEqual('/admin_mountpoint/?_data_changed=1',
                      new_response['Location'])
コード例 #24
0
    def get_subclass_type(self, obj):
        """
        get the verbose name of the given object, which is likely a subclass

        .. note::
            By using this callable, we avoid the problem of being able to
            sort by headers in the changelists (including on the change form)

        :return: the subclass object's verbose name
        :rtype: string
        """
        modeladmin = get_modeladmin(obj)
        if hasattr(modeladmin, 'get_editregions_subclass_type'):
            value = modeladmin.get_editregions_subclass_type(obj=obj)
        else:
            value = obj._meta.verbose_name
        value = strip_tags(force_text(value))
        return self.get_changelist_link_html(obj, data=value,
                                             caller='subclass')
コード例 #25
0
    def get_ancestors_instead(self, context, region_name, content_object):
        # make sure we have the damn method we need.
        try:
            parents = content_object.get_ancestors()
        except AttributeError as e:
            parents = None
        if parents is None:
            try:
                modeladmin = get_modeladmin(content_object)
                parents = modeladmin.get_ancestors(obj=content_object)
            except (NotRegistered, AttributeError) as e:
                # parents will remain None
                pass
        if parents is None:
            # doesn't have ancestors conforming to the mptt/treebeard
            # API, so it's probably a custom model that is BROKEN.
            error = ("{cls!r}, or the ModelAdmin for it, should implement "
                     "`get_ancestors` to use the 'inherit' argument for "
                     "this template tag".format(
                         cls=content_object.__class__))
            if settings.DEBUG:
                raise ImproperlyConfigured(error)
            logger.error(error, exc_info=1)
            return ()

        # if there are parents, see if we can get values from them.
        for distance, parent in enumerate(reversed(parents), start=1):
            attach_configuration(parent, EditRegionConfiguration)
            parent_erc = get_configuration(parent)
            parent_results = self.fetch(parent_erc, region=region_name)
            chunks = tuple(self.do_render(context, parent_results))
            chunk_count = len(chunks)
            if chunk_count > 0:
                logging.info("Found {1} chunks after {0} iterations over "
                             "objects in `get_ancestors`".format(
                                 distance, chunk_count))
                # stop processing further, we found some results!
                return chunks
        logging.debug("Inheriting from an ancestor yielded nothing")
        return ()
コード例 #26
0
    def test_save_model(self):
        user = User(username='******')
        user.set_password('test')
        user.full_clean()
        user.save()
        ct = get_content_type(User)
        iframe = Iframe(position=2, region='test', content_type=ct,
                        content_id=user.pk, url='https://news.bbc.co.uk/')
        iframe.full_clean()
        iframe.save()
        request = RequestFactory().get('/', data={
            'region': 'test',
            'content_type': ct.pk,
            'content_id': user.pk,
        })
        admin_instance = get_modeladmin(Iframe)

        expected_query_count = 2 if is_django_16plus() else 4
        with self.assertNumQueries(expected_query_count):
            result = admin_instance.save_model(request=request, obj=iframe,
                                               form=ModelForm, change=True)
            self.assertIsNone(result)
コード例 #27
0
    def test_autoclose_chunkadmin(self):
        """
        If `_autoclose` is in the URL, that + `_data_changed` should propagate
        to the next redirect URL for the purposes of our adminlinks JS.
        """
        user = User(username='******', is_staff=True, is_superuser=True,
                    is_active=True)
        user.set_password('test')
        user.full_clean()
        user.save()
        admin_instance = get_modeladmin(Iframe)
        self.assertIsInstance(admin_instance, RealishAdmin)

        request = RequestFactory().get('/', {
            '_autoclose': 1,
        })
        request.user = user
        iframe_admin = reverse('admin:embeds_iframe_add')
        response_301 = HttpResponsePermanentRedirect(redirect_to=iframe_admin)

        ct = get_content_type(User)
        iframe = Iframe(position=2, region='test', content_type=ct,
                        content_id=user.pk, url='https://news.bbc.co.uk/')
        iframe.full_clean()
        iframe.save()

        new_response = admin_instance.maybe_fix_redirection(
            request=request, response=response_301, obj=iframe)
        self.assertEqual(new_response['X-Chunkadmin-Response'], 'autoclose')

        self.assertEqual(301, new_response.status_code)
        location, querystring = new_response['Location'].split('?')
        self.assertEqual('/admin_mountpoint/embeds/iframe/add/', location)
        self.assertIn('region=test', querystring)
        self.assertIn('_data_changed=1', querystring)
        self.assertIn('_autoclose=1', querystring)
        self.assertIn('content_type={0}'.format(ct.pk), querystring)
        self.assertIn('content_id={0}'.format(iframe.pk), querystring)
コード例 #28
0
    def get_subclass_summary(self, obj):
        """
        show a brief, HTML aware summary of the content.

        .. note::
            By using this callable, we avoid the problem of being able to
            sort by headers in the changelists (including on the change form)

        :return: short representation of the data, HTML included.
        :rtype: string
        """
        modeladmin = get_modeladmin(obj)
        if hasattr(modeladmin, 'get_editregions_subclass_summary'):
            value = modeladmin.get_editregions_subclass_summary(obj=obj)
        elif hasattr(modeladmin, 'render_into_summary'):
            context = chunk_iteration_context(index=0, value=obj,
                                               iterable=(obj,))
            context.update({'admin_summary': True})
            value = modeladmin.render_into_summary(obj=obj, context=context)
        else:
            value = '[missing]'
        value = strip_tags(force_text(value))
        return self.get_changelist_link_html(obj, data=value,
                                             caller='summary')
コード例 #29
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_render_into_summary_no_data(self):
     self.file.data = None
     theadmin = get_modeladmin(self.file)
     out = theadmin.render_into_summary(obj=self.file, context=Context())
     self.assertEqual(out, 'x')
コード例 #30
0
ファイル: admin.py プロジェクト: kezabelle/django-editregions
 def test_render_into_summary(self):
     theadmin = get_modeladmin(self.file)
     out = theadmin.render_into_summary(obj=self.file, context=Context())
     self.assertEqual(out, 'x (z.gif)')