.. _topics-models:

===================
Models and Managers
===================

.. admonition:: About this document

   This document describes the Django model classes and custom managers provided
   by the library.

.. contents::
   :depth: 3

Models
======

Every model has an `UUID`_ as its primary key, called ``uuid``. UUIDs are
essential in allowing successful disconnected operation and subsequent
synchronization between multiple instances of a system. But these details are
handled by the synchronization tool. For what concerns everyday use of the wiki,
you can consider the ``uuid`` field in the same fashion of the *classical*
Django ``id`` automatic primary key.

.. _`UUID`: http://en.wikipedia.org/wiki/UUID


The ``Wiki`` model
------------------

A model which represents a single wiki instance.

``Wiki`` objects have the following fields:

``uuid``
    The object primary key.

``parent``
    ``Wiki`` objects can be hierarchical, or, in other words, a ``Wiki`` can have many
    children. This field is a ForeignKey to ``self``, describing the parent for
    the object, or null (``None``).

``name``
    The ``Wiki`` name.

``desc``
    A short description of the ``Wiki``.

``long_desc``
    A long description of the ``Wiki``, in `Markdown`_ format.

``publish``
    A boolean indicating if the ``Wiki`` is published or not. Only published
    ``Wiki`` objects are displayed in list views.

``publish_from``
    A start date for publication, or ``None``. If specified, the ``Wiki`` is
    considered published only after the specified value.

``publish_to``
    An ending date for publication, or ``None``. If specified, the ``Wiki`` is
    considered published only before the specified value.

``homepage``
    A ForeignKey to a ``Page`` instance. If not null, this ``Page`` is displayed
    when the ``Wiki`` is selected.

``author``
    The ``User`` who created the ``Wiki`` object.

``modifiedby``
    The ``User`` who modified last the ``Wiki`` object.

``created``
    The date and time when the ``Wiki`` object was created.

``modified``
    The date and time when the ``Wiki`` object was modified last.

``fullname_cache``
    A *service* field. Used to store the `qualified name` of the ``Wiki``. A
    `qualified name` is the name complete with components from the ancestors for
    the ``Wiki``. For example, if there is a root *Main* ``Wiki``, with a
    sub-``Wiki`` named *Recipes*, and a sub-sub-``Wiki`` named *Cakes*, the
    `qualified name` for this last ``Wiki`` is *"Main|Recipes|Cakes"*.
    **Please note**: you should never modify directly this field, or even
    access it. Use the ``fullname`` *property* instead.

``fullname_url_cache``
    A *service* field. This has the same use of ``fullname_cache`` but is used
    for URLs.
    **Please note**: you should never modify directly this field, or even
    access it. Use the ``fullname_url`` *property* instead.

The `(parent, name)` tuple must be unique, which is to say that two ``Wiki``
objects with the same parent must have a different ``name``.

Properties
~~~~~~~~~~

``fullname``
    A **read-only** property returning the `qualified name` for the ``Wiki``.

``fullname_url``
    A **read-only** property returning the `qualified URL name` for the ``Wiki``.

``absolutename``
    A synonym for ``fullname``. This is present for symmetry with the other
    models.

``absolutename_url``
    A synonym for ``fullname_url``. This is present for symmetry with the
    other models.

Methods
~~~~~~~

``ancestors(self, include_self=False)``
    This method returns the list of ancestors for the object.

``ancestors_with_self(self)``
    Same as ``ancestors(True)``.

.. _`Markdown`: http://daringfireball.net/projects/markdown/syntax


The ``Page`` model
------------------

Instances of this model represent single ``Wiki`` pages.

``Page`` objects have the following fields:

``uuid``
    The object primary key.

``parent``
    ``Page`` objects can be hierarchical too, in that a ``Page`` can have many
    sub-pages. This field is a ForeignKey to ``self``, describing the parent for
    the object, or null (``None``).

``wiki``
    A ForeignKey to the ``Wiki`` for this page. Can't be null.

``name``
    The ``Page`` name.

``desc``
    A short description of the ``Page``.

``up``
    A link to the *upper* page. Can be used to navigate between pages.

``prev``
    A link to the *previous* page. Can be used to navigate between pages.

``next``
    A link to the *next* page. Can be used to navigate between pages.

``publish``
    A boolean indicating if the ``Page`` is published or not. Only published
    ``Page`` objects are displayed in list views.

``publish_from``
    A start date for publication, or ``None``. If specified, the ``Page`` is
    considered published only after the specified value.

``publish_to``
    An ending date for publication, or ``None``. If specified, the ``Page`` is
    considered published only before the specified value.

``author``
    The ``User`` who created the ``Page`` object.

``modifiedby``
    The ``User`` who modified last the ``Page`` object.

``created``
    The date and time when the ``Page`` object was created.

``modified``
    The date and time when the ``Page`` object was modified last.

``fullname_cache``
    A *service* field. Used to store the `qualified name` of the ``Page``. A
    `qualified name` is the name complete with components from the ancestors for
    the ``Page``. For example, if there is a root *Lasagne* ``Page``, with a
    sub-``Page`` named *Bolognese*, the `qualified name` for this last ``Page``
    is *"Lasagne|Bolognese"*.
    **Please note**: you should never modify directly this field, or even
    access it. Use the ``fullname`` *property* instead.

``fullname_url_cache``
    A *service* field. This has the same use of ``fullname_cache`` but is used
    for URLs.
    **Please note**: you should never modify directly this field, or even
    access it. Use the ``fullname_url`` *property* instead.

The `(wiki, parent, name)` tuple must be unique, which is to say that two ``Wiki``
objects with the same parent must have a different ``name``.

Properties
~~~~~~~~~~

``fullname``
    A **read-only** property returning the `qualified name` for the ``Wiki``.

``fullname_url``
    A **read-only** property returning the `qualified URL name` for the ``Wiki``.

``absolutename``
    A **read-only** property returning the `absolute qualified name` for the
    ``Page``. The `absolute qualified name` also contains the ``Wiki`` qualified
    name, with the format *WikiQualifiedName* "." *PageQualifiedName*. For
    example, the aforementioned *"Lasagne|Bolognese"* absolute qualified name
    would be *"Main|Recipes|Cakes.Lasagne|Bolognese"*

``absolutename_url``
    A **read-only** property returning the `absolute URL qualified name` for the
    ``Page``.

Methods
~~~~~~~

``get_content(self, rev=None)``
    Return the ``PageContent`` instance for this ``Page`` with the specified
    `rev` revision, or the most recent if `rev` is ``None``.

``ancestors(self, include_self=False)``
    This method returns the list of ancestors for the object.

``ancestors_with_self(self)``
    Same as ``ancestors(True)``.

.. _`Markdown`: http://daringfireball.net/projects/markdown/syntax


The ``PageContent`` model
-------------------------

``PageContent`` instances contain the textual content of a ``Page``. For a given
``Page`` object, each ``PageContent`` instance represents a different revision.

``PageContent`` objects have the following fields:

``uuid``
    The object primary key.

``page``
    The ``Page`` object *containing* this content. Can't be null.

``rev``
    The revision for this content. It's a positive integer, starting at 1.

``title``
    The content title.

``text``
    The content text, in `wiki syntax`_.

``text_html``
    A *service* field. The content text translated in HTML. Unused, right now.

``references``
    A many-to-many relation to ``Page``. This represents a list of pages which
    should be considered related to this content. The user can set this list
    using the page form.

``linked``
    A many-to-many relation to ``Page``. Unlike ``references``, this is handled
    automatically by the wiki engine. Whenever a ``PageContent`` is modified,
    this field is set to the list of ``Page`` objects linked in the text.

``author``
    The ``User`` who created the ``PageContent`` object.

``modifiedby``
    The ``User`` who modified last the ``PageContent`` object. Note that by
    design this is always equal to ``author``, since a ``PageContent`` instance
    can't be modified with the provided forms, but every change leads to a new
    instance, with a greater revision. This field is present for symmetry.

``created``
    The date and time when the ``PageContent`` object was created.

``modified``
    The date and time when the ``PageContent`` object was modified last. Note
    that by design this is always equal to ``created``.

Properties
~~~~~~~~~~

``wiki``
    The ``Wiki`` of this ``PageContent``. A **read-only** property.

Methods
~~~~~~~

``same_content(self, other_pagecontent)``
    Compares the text fields with another ``PageContent`` instance.

.. _`wiki syntax`: syntax.html
.. _`Markdown`: http://daringfireball.net/projects/markdown/syntax

The ``Attachment`` model
------------------------

``Attachment`` instances represent file attachments to ``Page`` objects.
Each ``Page`` instance can have multiple ``Attachment`` instances.

``Attachment`` objects have the following fields:

``uuid``
    The object primary key.

``page``
    The ``Page`` object of this attachment. Can't be null.

``name``
    The attachment name. Can't be empty.

``desc``
    The attachment description.

``attachment``
    The ``FileField`` representing the attachment file. The file is uploaded to
    a subdirectory of ``MEDIA_ROOT`` of the form
    ``page-UU...UU/YYYYMMDD/FILENAME``, where ``UU...UU`` represents the ``Page``
    UUID.

``author``
    The ``User`` who created the ``Attachment`` object.

``modifiedby``
    The ``User`` who modified last the ``Attachment`` object.

``created``
    The date and time when the ``Attachment`` object was created.

``modified``
    The date and time when the ``Attachment`` object was modified last.

The `(page, name)` tuple must be unique, which is to say that two ``Attachment``
objects in the same ``Page`` must have a different ``name``.
