Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik committed Jun 29, 2012
2 parents 91e4100 + 8e3587e commit ee55c00
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 42 deletions.
2 changes: 2 additions & 0 deletions camelot/core/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ def __init__( self, author, name, data = 'data.sqlite' ):
if not os.path.exists( self._local_folder ):
os.makedirs( self._local_folder )

LOGGER.info( u'store database and media in %s'%self._local_folder )

def CAMELOT_MEDIA_ROOT(self):
return os.path.join( self._local_folder, 'media' )

Expand Down
6 changes: 4 additions & 2 deletions camelot/core/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ def decorated_function(cls, *args, **kwargs):
return decorated_function

def update_database_from_model():
"""Introspection the model and add missing columns in the database
"""Introspection the model and add missing columns in the database.
this function can be ran in setup_model after::
this function can be ran in setup_model after setup_all(create_tables=True)
metadata.create_all()
"""
migrate_engine = settings.ENGINE()
migrate_connection = migrate_engine.connect()
Expand Down
2 changes: 1 addition & 1 deletion camelot/view/controls/formview.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def set_toolbar_actions(self, actions):
qaction.triggered.connect( self.action_triggered )
toolbar.addAction( qaction )
toolbar.addWidget( BusyWidget() )
layout.insertWidget( 0, toolbar, 0, 0 )
layout.insertWidget( 0, toolbar, 0, Qt.AlignTop )

@QtCore.pyqtSlot( bool )
def action_triggered( self, _checked = False ):
Expand Down
2 changes: 2 additions & 0 deletions doc/sphinx/source/doc/fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ The types used mosed common are :
.. autoclass:: sqlalchemy.types.Unicode
:noindex:

.. _camelot-column-types:

Camelot column types
--------------------

Expand Down
4 changes: 0 additions & 4 deletions doc/sphinx/source/doc/schemas.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,3 @@ settings.py before anything else happens::
version = repository.latest
schema.upgrade(version)
migrate_connection.close()

Where settings.REPOSITORY is the directory of the sqlalchemy-migrate
repository. For more source code, have a look at the source of
:module:`camelot.bin.camelot_manage`.
52 changes: 28 additions & 24 deletions doc/sphinx/source/tutorial/videostore.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,17 @@ Let's first take a look at the :file:`main.py` in our project directory.
It contains a `my_settings` object which is appended to the global `settings`.
The :ref:`settings` object contains the global configuration for things such as database and file location.

.. literalinclude:: ../../../../new_project/main.py
:start-after: begin custom settings
:end-before: end custom settings

Now we can look at :file:`model.py`. Camelot has already imported some classes
for us. They are used to create our entities. Let's say we want a movie entity
with a ``title``, a short ``description``, a ``release date``, and a
``genre``.

The aforementioned specifications translate into the following Python code,
that we add to our model.py module::
that we add to our :file:`model.py` module::

from sqlalchemy import Unicode, Date
from sqlalchemy.schema import Column
Expand All @@ -153,10 +157,8 @@ that we add to our model.py module::
The complete source code of this tutorial can be found in the
:file:`camelot_example` folder of the Camelot source code.

``Movie`` inherits ``Entity``. ``Entity`` is the base class for all objects
that should be stored in the database. We use the ``__tablename__`` attribute to
to name the table ourselves in which the data will be stored, otherwise a
default tablename would have been used.
:class:`Movie` inherits :class:`Entity`. :class:`camelot.core.orm.Entity`` is the declarative base class for all objects that should be stored in the database.
We use the ``__tablename__`` attribute to to name the table ourselves in which the data will be stored, otherwise a default tablename would have been used.

Our entity holds four fields that are stored in columns in the table.

Expand All @@ -179,14 +181,12 @@ Our entity holds four fields that are stored in columns in the table.

``release_date`` holds a date, and ``genre`` up to 15 unicode characters:

For more information about defining models, refer to the
`SQLAlchemy Declarative extension <http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/declarative.html>`_.
For more information about defining models, refer to the `SQLAlchemy Declarative extension <http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/declarative.html>`_.

The different `SQLAlchemy <http://www.sqlalchemy.org>`_ column types used
are described `here <http://docs.sqlalchemy.org/en/rel_0_7/core/types.html>`_.
Finally, custom Camelot fields are documented in the API.
The different `SQLAlchemy <http://www.sqlalchemy.org>`_ column types used are described `here <http://docs.sqlalchemy.org/en/rel_0_7/core/types.html>`_.
Finally, custom Camelot fields are documented in the section :ref:`camelot-column-types`.

Let's now create an ``EntityAdmin`` subclass
Let's now create an :class:`EntityAdmin` subclass


The EntityAdmin Subclass
Expand Down Expand Up @@ -242,17 +242,14 @@ Let's move onto the last piece of the puzzle.
Configuring the Application
===========================

We are now working with :file:`application_admin.py`. One of
the tasks of :file:`application_admin.py` is to specify the sections in
the left pane of the main window.
We are now working with :file:`application_admin.py`.
One of the tasks of :file:`application_admin.py` is to specify the sections in the left pane of the main window.

Camelot defined a class, ``MyApplicationAdmin``, for us. This class is a
subclass of class:`camelot.admin.application_admin.ApplicationAdmin`, which is
used to control the overall look and feel of every Camelot application.
Camelot defined a class, ``MyApplicationAdmin``, for us.
This class is a subclass of :class:`camelot.admin.application_admin.ApplicationAdmin`, which is used to control the overall look and feel of every Camelot application.

To change sections in the left pane of the main window, simply overwrite the
``get_sections`` method, to return a list of the desired sections. By default
this method contains::
To change sections in the left pane of the main window, simply overwrite the ``get_sections`` method, to return a list of the desired sections.
By default this method contains::

def get_sections(self):
from camelot.model.memento import Memento
Expand All @@ -267,7 +264,7 @@ this method contains::
items = [Memento, Translation] )
]
which will display two buttons in the navigation pane, labelled ``'Relations'``
which will display two buttons in the navigation pane, labelled ``'My classes'``
and ``'Configurations'``, with the specified icon next to each label. And yes,
the order matters.

Expand Down Expand Up @@ -309,7 +306,7 @@ Camelot. Next we look at relationships between entities.
Relationships
=============

We will be using SQLAlchemy's :class:`sqlalchemy.orm.relationship` API. We'll
We will be using SQLAlchemy's :mod:`sqlalchemy.orm.relationship` API. We'll
relate a director to each movie. So first we need a ``Director`` entity. We
define it as follows::
Expand Down Expand Up @@ -387,8 +384,15 @@ follows::

.. note::

Whenever the model changes, the database needs to be updated. This can
be done by dropping and recreating the database (or deleting the sqlite file).
Whenever the model changes, the database needs to be updated.
This can be done by hand, or by dropping and recreating the database (or deleting the sqlite file).
By default Camelot stores the data in an local directory specified by the operating system.
Look in the startup logs to see where they are stored on your system, look for a line like ::
[INFO ] [camelot.core.conf] - store database and media in /home/username/.camelot/videostore

To simply add columns and tables, the function :func:`camelot.core.sql.update_database_from_model`
can be used.

For completeness the two entities are once again listed below::

Expand Down
4 changes: 2 additions & 2 deletions news.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Master
* Add a toolbar to the form view, configurable through
the :meth:`camelot.admin.object_admin.ObjectAdmin.get_form_toolbar_actions` method.

* Move the progress widget from the status bar to the toolbar
* Move the progress widget from the removed status bar to the toolbar

* Add :class:`camelot.admin.table.ColumnGroup` in the list view.

Expand All @@ -29,7 +29,7 @@ Master

* Store user changed column width in settings and :ref:`field-attribute-column_width` field attribute

* not_editable_admin has an `actions` argument
* :func:`camelot.admin.not_editable_admin.not_editable_admin` has an `actions` argument

* Reworked searching for translation files

Expand Down
18 changes: 9 additions & 9 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
Camelot
##########

Camelot provides components for building business applications on top
*SQLAlchemy* and *Qt*. It is inspired by the Django admin interface. A simple
piece of code as this::
Camelot provides components for building business applications on top of **Python**, **SQLAlchemy** and **Qt**.
It is inspired by the Django admin interface.
A simple piece of code as this::

class Movie( Entity ):
title = Column( Unicode( 60 ), nullable = False )
short_description = Column( Unicode( 512 ) )
release_date = Column( Date() )
class Task( Entity ):
short_description = Column( Unicode( 60 ), nullable = False )
due_date = Column( Date() )
long_description = Column( RichText() )

class Admin(EntityAdmin):
list_display = ['title', 'short_description', 'release_date']
class Admin( EntityAdmin ):
list_display = ['short_description', 'due_date']

Is enough to define your database schema, define the mapping between the
database and objects, and to create a user friendly desktop GUI.
Expand Down

0 comments on commit ee55c00

Please sign in to comment.