def __init__(self, model, admin_site): ensure_completely_loaded() if len(model._feincms_templates) > 4 and \ 'template_key' in self.radio_fields: del(self.radio_fields['template_key']) super(PageAdmin, self).__init__(model, admin_site) # The use of fieldsets makes only fields explicitly listed in there # actually appear in the admin form. However, extensions should not be # aware that there is a fieldsets structure and even less modify it; # we therefore enumerate all of the model's field and forcibly add them # to the last section in the admin. That way, nobody is left behind. from django.contrib.admin.util import flatten_fieldsets present_fields = flatten_fieldsets(self.fieldsets) for f in self.model._meta.fields: if (not f.name.startswith('_') and not f.name in ('id', 'lft', 'rght', 'tree_id', 'level') and not f.auto_created and not f.name in present_fields and f.editable): self.fieldsets[1][1]['fields'].append(f.name) warnings.warn( 'Automatically adding %r to %r.fieldsets. This behavior' ' is deprecated. Use add_extension_options yourself if' ' you want fields to appear in the page' ' administration.' % (f.name, self.__class__), DeprecationWarning) if not f.editable: self.readonly_fields.append(f.name)
def __init__(self, model, admin_site): ensure_completely_loaded() if len(model._feincms_templates) > 4 and "template_key" in self.radio_fields: del (self.radio_fields["template_key"]) super(PageAdmin, self).__init__(model, admin_site)
def __init__(self, *args, **kwargs): ensure_completely_loaded() if len(Page._feincms_templates) > 4 and "template_key" in self.radio_fields: del (self.radio_fields["template_key"]) super(PageAdmin, self).__init__(*args, **kwargs) # The use of fieldsets makes only fields explicitly listed in there # actually appear in the admin form. However, extensions should not be # aware that there is a fieldsets structure and even less modify it; # we therefore enumerate all of the model's field and forcibly add them # to the last section in the admin. That way, nobody is left behind. from django.contrib.admin.util import flatten_fieldsets present_fields = flatten_fieldsets(self.fieldsets) for f in self.model._meta.fields: if ( not f.name.startswith("_") and not f.name in ("id", "lft", "rght", "tree_id", "level") and not f.auto_created and not f.name in present_fields and f.editable ): self.unknown_fields.append(f.name) if not f.editable: self.readonly_fields.append(f.name)
def __init__(self, *args, **kwargs): ensure_completely_loaded() if 'initial' in kwargs: if 'parent' in kwargs['initial']: # Prefill a few form values from the parent page try: page = Page.objects.get(pk=kwargs['initial']['parent']) data = model_to_dict(page) for field in PageManager.exclude_from_copy: if field in data: del data[field] # These are always excluded from prefilling for field in self.never_copy_fields: if field in data: del data[field] kwargs['initial'].update(data) except Page.DoesNotExist: pass elif 'translation_of' in kwargs['initial']: # Only if translation extension is active try: page = Page.objects.get(pk=kwargs['initial']['translation_of']) original = page.original_translation data = { 'translation_of': original.id, 'template_key': original.template_key, 'active': original.active, 'in_navigation': original.in_navigation, } if original.parent: try: data['parent'] = original.parent.get_translation(kwargs['initial']['language']).id except Page.DoesNotExist: # ignore this -- the translation does not exist pass kwargs['initial'].update(data) except Page.DoesNotExist: pass super(PageAdminForm, self).__init__(*args, **kwargs) if 'instance' in kwargs: choices = [] for key, template in kwargs['instance'].TEMPLATE_CHOICES: template = kwargs['instance']._feincms_templates[key] if template.preview_image: choices.append((template.key, mark_safe(u'<img src="%s" alt="%s" /> %s' % ( template.preview_image, template.key, template.title)))) else: choices.append((template.key, template.title)) self.fields['template_key'].choices = choices
def __init__(self, model, admin_site): ensure_completely_loaded() if len(model._feincms_templates) > 4 and "template_key" in self.radio_fields: del self.radio_fields["template_key"] super(PageAdmin, self).__init__(model, admin_site)
def _needs_content_types(cls): ensure_completely_loaded() # Check whether any content types have been created for this base class if not hasattr(cls, '_feincms_content_types' ) or not cls._feincms_content_types: raise ImproperlyConfigured, 'You need to create at least one content type for the %s model.' % ( cls.__name__)
def __init__(self, model, admin_site): ensure_completely_loaded() if len(model._feincms_templates) > 4 and \ 'template_key' in self.radio_fields: del (self.radio_fields['template_key']) super(PostAdmin, self).__init__(model, admin_site)
def _needs_templates(cls): ensure_completely_loaded() # helper which can be used to ensure that either register_regions or # register_templates has been executed before proceeding if not hasattr(cls, 'template'): raise ImproperlyConfigured, 'You need to register at least one template or one region on %s.' % ( cls.__name__, )
def _needs_content_types(cls): ensure_completely_loaded() # Check whether any content types have been created for this base class if not hasattr(cls, "_feincms_content_types") or not cls._feincms_content_types: raise ImproperlyConfigured, "You need to create at least one content type for the %s model." % ( cls.__name__ )
def _needs_templates(cls): ensure_completely_loaded() # helper which can be used to ensure that either register_regions # or register_templates has been executed before proceeding if not hasattr(cls, 'template'): raise ImproperlyConfigured('You need to register at least one' ' template or one region on %s.' % cls.__name__)
def __init__(self, model, admin_site): ensure_completely_loaded() super(ItemEditor, self).__init__(model, admin_site) # Add inline instances for FeinCMS content inlines for inline_class in get_feincms_inlines(model): inline_instance = inline_class(self.model, self.admin_site) self.inline_instances.append(inline_instance)
def __init__(self, model, admin_site): ensure_completely_loaded() super(ItemEditor, self).__init__(model, admin_site) # Add inline instances for FeinCMS content inlines for inline_class in self.get_feincms_inlines(model): inline_instance = inline_class(self.model, self.admin_site) self.inline_instances.append(inline_instance)
def _needs_content_types(cls): ensure_completely_loaded() # Check whether any content types have been created for this base # class if (not hasattr(cls, '_feincms_content_types') or not cls._feincms_content_types): raise ImproperlyConfigured('You need to create at least one' ' content type for the %s model.' % cls.__name__)
def _needs_content_types(cls): ensure_completely_loaded() # Check whether any content types have been created for this base # class if not getattr(cls, '_feincms_content_types', None): raise ImproperlyConfigured('You need to create at least one' ' content type for the %s model.' % cls.__name__)
def _template(self): ensure_completely_loaded() try: return self._feincms_templates[self.template_key] except KeyError: # return first template as a fallback if the template # has changed in-between return self._feincms_templates[self._feincms_templates.keys()[0]]
def __init__(self, model, admin_site): ensure_completely_loaded() super(ItemEditor, self).__init__(model, admin_site) if hasattr(self, 'inline_instances'): # Add inline instances for FeinCMS content inlines # This works in Django 1.3 and lower # In Django 1.4 inline instances are generated using overridden get_inline_instances() self.append_feincms_inlines(self.inline_instances)
def _needs_content_types(cls): ensure_completely_loaded() # Check whether any content types have been created for this base # class if not getattr(cls, "_feincms_content_types", None): raise ImproperlyConfigured( "You need to create at least one" " content type for the %s model." % cls.__name__ )
def _template(self): ensure_completely_loaded() try: return self._feincms_templates[self.template_key] except KeyError: # return first template as a fallback if the template # has changed in-between return self._feincms_templates[ list(self._feincms_templates.keys())[0]]
def __init__(self, *args, **kwargs): ensure_completely_loaded() if len(Page._feincms_templates) > 4 and 'template_key' in self.radio_fields: del(self.radio_fields['template_key']) super(PageAdmin, self).__init__(*args, **kwargs) # The use of fieldsets makes only fields explicitly listed in there # actually appear in the admin form. However, extensions should not be # aware that there is a fieldsets structure and even less modify it; # we therefore enumerate all of the model's field and forcibly add them # to the last section in the admin. That way, nobody is left behind. from django.contrib.admin.util import flatten_fieldsets present_fields = flatten_fieldsets(self.fieldsets) for f in self.model._meta.fields: if not f.name.startswith('_') and not f.name in ('id', 'lft', 'rght', 'tree_id', 'level') and \ not f.auto_created and not f.name in present_fields and f.editable: self.unknown_fields.append(f.name) if not f.editable: self.readonly_fields.append(f.name)
def create_content_type(cls, model, regions=None, class_name=None, **kwargs): """ This is the method you'll use to create concrete content types. If the CMS base class is ``page.models.Page``, its database table will be ``page_page``. A concrete content type which is created from ``ImageContent`` will use ``page_page_imagecontent`` as its table. If you want a content type only available in a subset of regions, you can pass a list/tuple of region keys as ``regions``. The content type will only appear in the corresponding tabs in the item editor. If you use two content types with the same name in the same module, name clashes will happen and the content type created first will shadow all subsequent content types. You can work around it by specifying the content type class name using the ``class_name`` argument. Please note that this will have an effect on the entries in ``django_content_type``, on ``related_name`` and on the table name used and should therefore not be changed after running ``syncdb`` for the first time. Name clashes will also happen if a content type has defined a relationship and you try to register that content type to more than one Base model (in different modules). Django will raise an error when it tries to create the backward relationship. The solution to that problem is, as shown above, to specify the content type class name with the ``class_name`` argument. If you register a content type to more than one Base class, it is recommended to always specify a ``class_name`` when registering it a second time. You can pass additional keyword arguments to this factory function. These keyword arguments will be passed on to the concrete content type, provided that it has a ``initialize_type`` classmethod. This is used f.e. in ``MediaFileContent`` to pass a set of possible media positions (f.e. left, right, centered) through to the content type. """ if not class_name: class_name = model.__name__ # prevent double registration and registration of two different # content types with the same class name because of related_name # clashes try: getattr(cls, '%s_set' % class_name.lower()) warnings.warn( 'Cannot create content type using %s.%s for %s.%s,' ' because %s_set is already taken.' % ( model.__module__, class_name, cls.__module__, cls.__name__, class_name.lower()), RuntimeWarning) return except AttributeError: # everything ok pass if django.VERSION < (1, 7): # Next name clash test. Happens when the same content type is # created for two Base subclasses living in the same Django # application (github issues #73 and #150) # # FIXME This code does not work with Django 1.7, because # get_model depends on the app cache which is not ready at # this time yet. try: other_model = get_model(cls._meta.app_label, class_name) if other_model is None: # Django 1.6 and earlier raise LookupError except LookupError: pass else: warnings.warn( 'It seems that the content type %s exists twice in %s.' ' Use the class_name argument to create_content_type' ' to avoid this error.' % ( model.__name__, cls._meta.app_label), RuntimeWarning) if not model._meta.abstract: raise ImproperlyConfigured( 'Cannot create content type from' ' non-abstract model (yet).') if not hasattr(cls, '_feincms_content_model'): cls._create_content_base() feincms_content_base = cls._feincms_content_model class Meta(feincms_content_base.Meta): db_table = '%s_%s' % (cls._meta.db_table, class_name.lower()) verbose_name = model._meta.verbose_name verbose_name_plural = model._meta.verbose_name_plural permissions = model._meta.permissions attrs = { # put the concrete content type into the # same module as the CMS base type; this is # necessary because 1. Django needs to know # the module where a model lives and 2. a # content type may be used by several CMS # base models at the same time (f.e. in # the blog and the page module). '__module__': cls.__module__, 'Meta': Meta, } new_type = type( str(class_name), (model, feincms_content_base,), attrs, ) cls._feincms_content_types.append(new_type) if hasattr(getattr(new_type, 'process', None), '__call__'): cls._feincms_content_types_with_process.append(new_type) if hasattr(getattr(new_type, 'finalize', None), '__call__'): cls._feincms_content_types_with_finalize.append(new_type) # content types can be limited to a subset of regions if not regions: regions = set([ region.key for region in cls._feincms_all_regions]) for region in cls._feincms_all_regions: if region.key in regions: region._content_types.append(new_type) # Add a list of CMS base types for which a concrete content type # has been created to the abstract content type. This is needed # f.e. for the update_rsscontent management command, which needs to # find all concrete RSSContent types, so that the RSS feeds can be # fetched if not hasattr(model, '_feincms_content_models'): model._feincms_content_models = [] model._feincms_content_models.append(new_type) # Add a backlink from content-type to content holder class new_type._feincms_content_class = cls # Handle optgroup argument for grouping content types in the item # editor optgroup = kwargs.pop('optgroup', None) if optgroup: new_type.optgroup = optgroup # customization hook. if hasattr(new_type, 'initialize_type'): new_type.initialize_type(**kwargs) else: for k, v in kwargs.items(): setattr(new_type, k, v) # collect item editor context processors from the content type if hasattr(model, 'feincms_item_editor_context_processors'): cls.feincms_item_editor_context_processors.extend( model.feincms_item_editor_context_processors) # collect item editor includes from the content type if hasattr(model, 'feincms_item_editor_includes'): for key, incls in model.feincms_item_editor_includes.items(): cls.feincms_item_editor_includes.setdefault( key, set()).update(incls) ensure_completely_loaded(force=True) return new_type
def __init__(self, model, admin_site): ensure_completely_loaded() super(ItemEditor, self).__init__(model, admin_site)
def __init__(self, *args, **kwargs): ensure_completely_loaded() if 'initial' in kwargs: if 'parent' in kwargs['initial']: # Prefill a few form values from the parent page try: page = self.page_manager.get( pk=kwargs['initial']['parent']) data = model_to_dict(page) for field in self.page_manager.exclude_from_copy: if field in data: del data[field] # These are always excluded from prefilling for field in self.never_copy_fields: if field in data: del data[field] data.update(kwargs['initial']) if page.template.child_template: data['template_key'] = page.template.child_template kwargs['initial'] = data except self.page_model.DoesNotExist: pass elif 'translation_of' in kwargs['initial']: # Only if translation extension is active try: page = self.page_manager.get( pk=kwargs['initial']['translation_of']) original = page.original_translation data = { 'translation_of': original.id, 'template_key': original.template_key, 'active': original.active, 'in_navigation': original.in_navigation, } if original.parent: try: data['parent'] = original.parent.get_translation( kwargs['initial']['language'] ).id except self.page_model.DoesNotExist: # ignore this -- the translation does not exist pass data.update(kwargs['initial']) kwargs['initial'] = data except (AttributeError, self.page_model.DoesNotExist): pass # Not required, only a nice-to-have for the `redirect_to` field modeladmin = kwargs.pop('modeladmin', None) super(PageAdminForm, self).__init__(*args, **kwargs) if modeladmin and 'redirect_to' in self.fields: # Note: Using `parent` is not strictly correct, but we can be # sure that `parent` always points to another page instance, # and that's good enough for us. self.fields['redirect_to'].widget = RedirectToWidget( self.page_model._meta.get_field('parent').rel, modeladmin.admin_site) if 'template_key' in self.fields: choices = [] for key, template_name in self.page_model.TEMPLATE_CHOICES: template = self.page_model._feincms_templates[key] pages_for_template = self.page_model._default_manager.filter( template_key=key) pk = kwargs['instance'].pk if kwargs.get('instance') else None other_pages_for_template = pages_for_template.exclude(pk=pk) if template.singleton and other_pages_for_template.exists(): continue # don't allow selection of singleton if in use if template.preview_image: choices.append(( template.key, mark_safe('<img src="%s" alt="%s" /> %s' % ( template.preview_image, template.key, template.title, )) )) else: choices.append((template.key, template.title)) self.fields['template_key'].choices = choices
# ------------------------------------------------------------------------ from __future__ import absolute_import, unicode_literals from django.contrib import admin from django.core.exceptions import ImproperlyConfigured from django.db.models import FieldDoesNotExist from feincms import ensure_completely_loaded, settings from .models import Page from .modeladmins import PageAdmin # ------------------------------------------------------------------------ if settings.FEINCMS_USE_PAGE_ADMIN: ensure_completely_loaded() try: Page._meta.get_field('template_key') except FieldDoesNotExist: raise ImproperlyConfigured( "The page module requires a 'Page.register_templates()' call " "somewhere ('Page.register_regions()' is not sufficient). " "If you're not using the default Page admin, maybe try " "FEINCMS_USE_PAGE_ADMIN=False to avoid this warning." ) admin.site.register(Page, PageAdmin) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------
def __init__(self, *args, **kwargs): ensure_completely_loaded() if "initial" in kwargs: if "parent" in kwargs["initial"]: # Prefill a few form values from the parent page try: page = Page.objects.get(pk=kwargs["initial"]["parent"]) data = model_to_dict(page) for field in PageManager.exclude_from_copy: if field in data: del data[field] # These are always excluded from prefilling for field in self.never_copy_fields: if field in data: del data[field] data.update(kwargs["initial"]) kwargs["initial"] = data except Page.DoesNotExist: pass elif "translation_of" in kwargs["initial"]: # Only if translation extension is active try: page = Page.objects.get(pk=kwargs["initial"]["translation_of"]) original = page.original_translation data = { "translation_of": original.id, "template_key": original.template_key, "active": original.active, "in_navigation": original.in_navigation, } if original.parent: try: data["parent"] = original.parent.get_translation(kwargs["initial"]["language"]).id except Page.DoesNotExist: # ignore this -- the translation does not exist pass data.update(kwargs["initial"]) kwargs["initial"] = data except (AttributeError, Page.DoesNotExist): pass super(PageAdminForm, self).__init__(*args, **kwargs) if "instance" in kwargs: choices = [] for key, template in kwargs["instance"].TEMPLATE_CHOICES: template = kwargs["instance"]._feincms_templates[key] if template.preview_image: choices.append( ( template.key, mark_safe( u'<img src="%s" alt="%s" /> %s' % (template.preview_image, template.key, template.title) ), ) ) else: choices.append((template.key, template.title)) self.fields["template_key"].choices = choices
# coding=utf-8 # ------------------------------------------------------------------------ from __future__ import absolute_import from django.contrib import admin from django.core.exceptions import ImproperlyConfigured from django.db.models import FieldDoesNotExist from feincms import ensure_completely_loaded, settings from .models import Page from .modeladmins import PageAdmin # ------------------------------------------------------------------------ if settings.FEINCMS_USE_PAGE_ADMIN: ensure_completely_loaded() try: Page._meta.get_field('template_key') except FieldDoesNotExist: raise ImproperlyConfigured( "The page module requires a 'Page.register_templates()' call " "somewhere ('Page.register_regions()' is not sufficient). " "If you're not using the default Page admin, maybe try " "FEINCMS_USE_PAGE_ADMIN=False to avoid this warning.") admin.site.register(Page, PageAdmin) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------