Base Models¶
-
class
widgy.models.base.Content[source]¶ -
Tree Traversal
With the exception
depth_first_order(), the following methods are all like the traversal API provided byTreebeard, but instead of returningNodes, they returnContents.-
depth_first_order(self)[source]¶ Convenience method for iterating over all the
Contentsin a subtree in order. This is similar to Treebeard’sget_descendants(), but includes itself.
Tree Manipulation
The following methods mirror those of
Node, but accept aWidgySiteas the first argument. You must call these methods onContentand not onNode.>>> root = Layout.add_root(widgy_site) >>> main = root.add_child(widgy_site, MainContent) >>> sidebar = main.add_sibling(widgy_site, Sidebar, title='Alerts') # move the sidebar to the left of the main content. >>> sidebar.reposition(widgy_site, right=main)
-
classmethod
add_root(cls, site, **kwargs)[source]¶ Creates a root node widget. Any kwargs will be passed to the Content class’s initialize method.
-
add_child(self, site, cls, **kwargs)[source]¶ Adds a new instance of
clsas the last child of the current widget.
-
add_sibling(self, site, cls, **kwargs)[source]¶ Adds a new instance of
clsto the right of the current widget.
-
reposition(self, site, right=None, parent=None)[source]¶ Moves the current widget to the left of
rightor to the last child position ofparent.
-
post_create(self, site)[source]¶ Hook for doing things after a widget has been created (a
Contenthas been created and put in the tree). This is useful if you want to have default children for a widget, for example.
-
delete(self, raw=False)[source]¶ If
rawisTruethe widget is being deleted due to a failure in widget creation, sopost_createwill not have been run yet.
-
clone(self)[source]¶ This method is called by
Node.clone_tree(). You may wish to override it if your Content has special needs like a ManyToManyField.Warning
Clone is used to freeze tree state in Versioning. If your
clone()method is incorrect, your history will be corrupt.
Editing
-
display_name¶ A human-readable short name for widgets. This defaults to the
verbose_nameof the widget.Hint
You can use the
@propertydecorator to make this dynamic.Todo
screenshot
-
tooltip¶ A class attribute that sets the tooltip for this widget on the shelf.
-
css_classes¶ A list of CSS classes to apply to the widget element in the Editor. Defaults to
app_labelandmodule_nameof the widget.
-
shelf = False Denotes whether this widget have a shelf. Root nodes automatically have a shelf. The shelf is where the widgets exist in the interface before they are dragged on. It is useful to set
shelftoTrueif there are a large number of widgets who can only go in a specfic subtree.
-
component_name = 'widget' Specifies which JavaScript component to use for this widget.
Todo
Write documentation about components.
-
pop_out = CANNOT_POP_OUT It is possible to open a subtree in its own editing window.
pop_outcontrols if a widget can be popped out. There are three values forpop_out:-
CANNOT_POP_OUT¶
-
CAN_POP_OUT¶
-
MUST_POP_OUT¶
-
-
form = ModelForm The form class to use for editing. Also see
get_form_class().
-
formfield_overrides = {} Similar to
ModelAdmin,Contentallows you to override the form fields for specific model field classes.
-
draggable = True Denotes whether this widget may be moved through the editing interface.
-
deletable = True Denotes whether this widget may be deleted through the editing interface.
-
editable = False Denotes whether this widget may be edited through the editing interface. Widgy will automatically generate a
ModelFormto provide the editing functionality. Also seeformandget_form_class().
-
preview_templates¶ A template name or list of template names for rendering in the widgy Editor. See
get_templates_hierarchy()for how the default value is derived.
-
edit_templates¶ A template name or list of template names for rendering the edit interface in the widgy Editor. See
get_templates_hierarchy()for how the default value is derived.
-
classmethod
get_templates_hierarchy(cls, **kwargs)[source]¶ Loops through MRO to return a list of possible template names for a widget. For example the preview template for something like
Tabsmight look like:widgy/page_builder/tabs/preview.htmlwidgy/mixins/tabbed/preview.htmlwidgy/page_builder/accordion/preview.htmlwidgy/page_builder/bucket/preview.htmlwidgy/models/content/preview.htmlwidgy/page_builder/preview.htmlwidgy/mixins/preview.htmlwidgy/page_builder/preview.htmlwidgy/models/preview.htmlwidgy/preview.html
Frontend Rendering
-
render(self, context, template=None)[source]¶ The method that is called by the
render()template tag to render the Content. It is useful to override this if you need to inject things into the context.
-
get_render_templates(self, context)[source]¶ Returns a template name or list of template names for frontend rendering.
Compatibility
Widgy provide robust machinery for compatibility between Contents. Widgy uses the compatibility system to validate the relationships between parent and child Contents.
Compatibility is checked when rendering the shelf and when adding or moving widgets in the tree.
-
accepting_children = False An easy compatibility configuration attribute. See
valid_parent_of()for more details.
-
valid_parent_of(self, cls, obj=None)[source]¶ If
objis provided, returnTrueif it could be a child of the current widget.clsis the type ofobj.If
objisn’t provided, returnTrueif a new instance ofclscould be a child of the current widget.objisNonewhen the child widget is being created or Widgy is checking the compatibility of the widgets on the shelf. If it is being moved from another location, there will be an instance. A parent and child are only compatible if bothvalid_parent_of()andvalid_child_of()returnTrue. This defaults to the value ofaccepting_children.Here is an example of a parent that only accepts three instances of
B:class A(Content): def valid_parent_of(self, cls, obj=None): # If this is already my child, it can stay my child. # This works for obj=None because self.get_children() # will never contain None. if obj in self.get_children(): return True else: # Make sure it is of type B return (issubclass(cls, B) # And that I don't already have three children. and len(self.get_children()) < 3)
-
classmethod
valid_child_of(cls, parent, obj=None)[source]¶ If
objis provided, returnTrueif it can be a child ofparent.objwill be an instance ofcls—it may feel like an instance method.If
objisn’t provided, returnTrueif a new instance ofclscould be a child ofparent.This defaults to
True.Here is an example of a Content that can not live inside another instance of itself:
class Foo(Content): @classmethod def valid_child_of(cls, parent, obj=None): for p in list(parent.get_ancestors()) + [parent]: if isinstance(p, Foo): return False return super(Foo, cls).valid_child_of(parent, obj)
-
-
class
widgy.models.base.Node[source]¶ -
-
is_frozen¶ A boolean field indicating whether this node is frozen and can’t be changed in any way. This is used to preserve old tree versions for versioning.
-
render(self, *args, **kwargs)[source]¶ Renders this subtree and returns a string. Normally you shouldn’t call it directly, use
widgy.db.fields.WidgyField.render()orwidgy.templatetags.widgy_tags.render().
-
depth_first_order(self)[source]¶ Like
Content.depth_first_order(), but over nodes.
-
prefetch_tree(self)[source]¶ Efficiently fetches an entire tree (or subtree), including content instances. It uses
1 + mqueries, wheremis the number of distinct content types in the tree.
-
classmethod
prefetch_trees(cls, *root_nodes)[source]¶ Prefetches multiple trees. Uses
n + mqueries, wherenis the number of trees andmis the number of distinct content types across all the trees.
-
classmethod
find_widgy_problems(cls, site=None)[source]¶ When a Widgy tree is edited without protection from a transaction, it is possible to get into an inconsistent state. This method returns a tuple containing two lists:
- A list of node pks whose content pointer is dangling – pointing to a content that doesn’t exist.
- A list of node pks whose content_type doesn’t exist. This might
happen when you switch branches and remove the code for a widget,
but still have the widget in your database. These are represented
by
UnknownWidgetinstances.
-