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
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
def setUp(self): request = RequestFactory().get('/') our_list_display = EditRegionAdmin.list_display our_list_links = (EditRegionAdmin(User, admin.site) .get_list_display_links(request=request, list_display=our_list_display)) user = User(username='******') user.set_password('test') user.full_clean() user.save() self.user = user user_content_type = get_content_type(User) attach_configuration(user, EditRegionConfiguration) config = get_configuration(user) request.GET = QueryDict('', mutable=True) request.GET.update({REQUEST_VAR_ID: user.pk, REQUEST_VAR_CT: user_content_type.pk, REQUEST_VAR_REGION: 'test'}) try: admin.site.unregister(User) except NotRegistered: pass admin.site.register(User, TestUserAdmin) cl = EditRegionChangeList(request=request, model=EditRegionChunk, list_display=our_list_display, list_display_links=our_list_links, list_filter=EditRegionAdmin.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=admin.site._registry[EditRegionChunk], # noqa parent_obj=user, parent_conf=config) self.changelist = cl badconfig = EditRegionConfiguration() cl2 = EditRegionChangeList(request=request, model=EditRegionChunk, list_display=our_list_display, list_display_links=our_list_links, list_filter=EditRegionAdmin.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=admin.site._registry[EditRegionChunk], # noqa parent_obj=user, parent_conf=badconfig) self.changelist2 = cl2
def get_value(self, context, name, content_object, inherit, nodelist): content_type = self.get_content_type(content_object) if content_type is None: return () # cache on the object so that showing the first editregion does the # configuration request, and additional ones re-use the config found. attach_configuration(content_object, EditRegionConfiguration) erc = get_configuration(content_object) results = self.fetch(erc, region=name) chunks = tuple(self.do_render(context, results)) if inherit and len(chunks) < 1: chunks = self.get_ancestors_instead(context, name, content_object) return chunks
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 ()
def clean(self): cd = super(MovementForm, self).clean() pk = cd.get('pk', None) model = self.get_model() try: if pk is None: raise model.DoesNotExist("Don't even bother querying") cd['pk'] = model.objects.get(pk=pk) except model.DoesNotExist as e: cd['pk'] = None name = force_text(self.get_model()._meta.verbose_name) msg = '{0} does not exist'.format(name) self._errors['pk'] = msg # rather than raise an error for an invalid region, just set it # back to whatever the region says it should be. Trust no-one. if 'region' in cd and cd['pk'] is not None: attach_configuration(cd['pk'].content_object, EditRegionConfiguration) erc = get_configuration(cd['pk'].content_object) if cd['region'] not in erc.config: msg = '{0} is not a valid region'.format(cd['region']) self._errors['region'] = msg return cd
def test_getting_without_having_attached(self): user = User() self.assertNotIsInstance(get_configuration(user), EditRegionConfiguration) self.assertIsNone(get_configuration(user))
def test_getting(self): user = User() obj, created = attach_configuration(user, EditRegionConfiguration) self.assertIsInstance(get_configuration(user), EditRegionConfiguration)
def get_editregion_config(self, obj): attach_configuration(obj, EditRegionConfiguration) try: return get_configuration(obj).tolist() except AttributeError: return None