Model View Controller
=====================

**Fantastico** framework provides quite a powerful model - view - controller implementation. Here you can find details about
design decisions and how to benefit from it.

Classic approach
----------------

Usually when you want to work with models as understood by MVC pattern you have in many cases boiler plate code:

#. Write your model class (or entity)
#. Write a repository that provides various methods for this model class.
#. Write a facade that works with the repository.
#. Write a web service / page that relies on the facade.
#. Write one or multiple views.

As this is usually a good in theory, in practice you will see that many methods from facade are converting a data transfer object
to an entity and pass it down to repository.

Fantastico approach
-------------------

**Fantastico** framework provides an alternative to this classic approach (you can still work in the old way if you really really
want).

.. autoclass:: fantastico.mvc.controller_decorators.Controller
    :members:
    
If you want to find more details and use cases for controller read :ref:`core-controller-section` section.
        
Model
-----

A model is a very simple object that inherits :py:class:`fantastico.mvc.models.BaseModel`.

In order for models to work correctly and to be injected correctly into controller you must make sure you have
a valid database configuration in your settings file. By default, :py:class:`fantastico.settings.BasicSettings` provides a usable
database configuration.

.. code-block:: python

    # fantastico.settings.BasicSettings
    @property
    def database_config(self):
        return {"drivername": "mysql+mysqldb",
                "username": "fantastico",
                "password": "12345",
                "host": "localhost",
                "port": 3306,
                "database": "fantastico",
                "show_sql": True}

By default, each time a new build is generated for fantastico each environment is validated to ensure connectivity to configured
database works.

There are multiple ways in how a model is used but the easiest way is to use an autogenerated model facade:

.. autoclass:: fantastico.mvc.model_facade.ModelFacade
    :members:
    
If you are using the **Fantastico MVC** support you don't need to manually create a model facade instance because
:py:class:`fantastico.mvc.controller_decorators.Controller` injects defined models automatically.

View
----

A view can be a simple html plain file or html + jinja2 enriched support. You can read more about **Jinja2** 
`here <http://jinja.pocoo.org/docs/>`_. Usually, if you need some logical block statements in your view (if, for, ...)
it is easier to use jinja 2 template engine. The good news is that you can easily embed jinja 2 markup in your views
and it will be rendered automatically.

.. _core-controller-section:

Controller
----------

A controller is the *brain*; it actually combines a model execute some business logic and pass data to the desired view
that needs to be rendered. In some cases you don't really need view in order to provide the logic you want:

    * A REST Web service.
    * A RSS feed provider.
    * A file download service
    
Though writing REST services does not require a view, you can load external text templates that might be useful for assembling the
response:

    * An invoice generator service
    * An xml file that must be filled with product data
    * A `vCard <http://en.wikipedia.org/wiki/VCard>`_. export service.
    
If you want to read a small tutorial and to start coding very fast on Fantastico MVC read :doc:`/how_to/mvc_how_to`. Controller
API is documented :py:class:`fantastico.mvc.controller_decorator.Controller`.

.. autoclass:: fantastico.mvc.controller_registrator.ControllerRouteLoader
    :members:
    
.. autoclass:: fantastico.mvc.base_controller.BaseController
    :members:

Available filters
~~~~~~~~~~~~~~~~~

.. autoclass:: fantastico.mvc.models.model_filter_compound.ModelFilterCompound
    :members:

.. autoclass:: fantastico.mvc.models.model_filter.ModelFilter
    :members:

.. autoclass:: fantastico.mvc.models.model_filter_compound.ModelFilterAnd
    :members:
    
.. autoclass:: fantastico.mvc.models.model_filter_compound.ModelFilterOr
    :members:

.. autoclass:: fantastico.mvc.models.model_sort.ModelSort
    :members:

Database session management
---------------------------

We all know database session management is painful and adds a lot of boiler plate code. In fantastico you don't need
to manage database session by yourself. There is a dedicated middleware which automatically ensures there is an
active session ready to be used:

.. autoclass:: fantastico.middleware.model_session_middleware.ModelSessionMiddleware
   :members: