[ADD] models intro
authorXavier Morel <xmo@openerp.com>
Wed, 29 Jan 2014 16:51:27 +0000 (17:51 +0100)
committerXavier Morel <xmo@openerp.com>
Mon, 19 May 2014 06:23:14 +0000 (08:23 +0200)
doc/howto/howto_website.rst
doc/howto/howto_website/series
doc/howto/howto_website/ta-data [new file with mode: 0644]
doc/howto/howto_website/ta-html-biography [new file with mode: 0644]
doc/howto/howto_website/ta-model [new file with mode: 0644]
doc/howto/howto_website/ta-t-field [new file with mode: 0644]
doc/howto/howto_website/ta-template-biography [new file with mode: 0644]
doc/howto/howto_website/ta-view-fix [new file with mode: 0644]
doc/howto/howto_website/website-layoutify

index 23939bc..e7052df 100644 (file)
@@ -308,9 +308,129 @@ structure:
 
 .. todo:: website template generator
 
+If you try to add content to the TA pages using snippets, for instance
+insert an :guilabel:`image-text` snippet to add a picture and a short
+biography for a TA, you'll notice things don't work right: because
+snippets are added in the template itself, they're content which is
+the same across all pages using that template.
+
+Thus snippets are mostly for generic content, when a given template is
+only used for a single page, or to add content in HTML fields.
+
+.. note::
+
+    When creating a new page (e.g. via :menuselection:`Content --> New
+    Page`), OpenERP will duplicate a "source" template, and create a
+    new template for each page. As a result, it's safe to use
+    dedicated-content snippets for "static" pages.
+
+Time, then, to create more specific content.
+
 Storing data in OpenERP
 =======================
 
+The conceptual storage model of OpenERP is simple: there are storage
+tables, represented by OpenERP models, and inside these tables are
+records. The first step, then, is to define a model.
+
+We'll start by moving our teaching assistants in the database:
+
+.. patch::
+
+We've also altered the index method slightly, to retrieve our teaching
+assistants from the database instead of storing them in a global list
+in the module\ [#taprofile]_.
+
+.. note:: :file:`ir.model.access.csv` is necessary to tell OpenERP that
+          any user can *see* the teaching assistants: by default, only
+          the administrator can see, edit, create or destroy objects.
+          Here, we only change the ``read`` permission to allow any
+          user to list and browse teaching assistants.
+
+.. todo:: command/shortcut
+
+Update the module, reload `your openerp`_… and the Teaching Assistants
+list is empty since we haven't put any TA in the database.
+
+Let's add them in data files:
+
+.. patch::
+
+Update the module again, reload `your openerp`_ and the TAs are
+back. Click on a TA name, and you'll see an error message. Let's fix
+the TA view now:
+
+.. todo:: if ta template was modified in previous section, it's marked
+          noupdate and updating the module will have no effect for no
+          known reason. That's really quite annoying.
+
+.. patch::
+
+There are a few non-obvious things here, so let's go through them for
+clarity:
+
+* OpenERP provides a has a special `converter pattern`_, which knows
+  how to retrieve OpenERP objects by identifier. Instead of an integer
+  or other similar basic value, ``ta`` thus gets a full-blown
+  ``academy.tas`` object, without having to retrieve it by hand (as is
+  done in ``index``).
+
+* However because the ``model()`` `converter pattern`_ takes an
+  identifier, we have to alter the creation of ``ta``'s URL to include
+  such an identifier, rather than an index in an array
+
+* Finally, ``website.render()`` wants a dict as its rendering context,
+  not an object, which is why we wrap our ``ta`` object into one.
+
+We're still where we started this section though: if we add snippets
+to or edit the text of a TA's page, these editions will be visible
+across all TA pages since they'll be stored in the shared
+``academy.ta`` template.
+
+Not only that, but we can not even edit the TA's name, even though
+it's not shared content.
+
+Let's fix that first, instead of using the basic "display this
+content" template tag ``t-esc``, we'll use one aware of OpenERP
+objects and their fields:
+
+.. patch::
+
+Update the module, go into a TA page and activate the edition mode. If
+you move your mouse over the TA's name, it is surrounded by a yellow
+border, and you can edit its content. If you change the name of a TA
+and save the page, the change is correctly stored in the TA's record,
+the name is fixed when you go to the index page but other TAs remain
+unaffected.
+
+For the issue of customizing our TA profiles, we can expand our model
+with a "freeform" HTML field:
+
+.. patch::
+
+Then, insert the new biographical content in the template using the
+same object-aware template tag:
+
+.. patch::
+
+.. todo:: updating the ``name`` field from the RTE altered the
+          template, which locked it...
+
+Update the module, browse to a TA's page and open the edition mode
+(using the :guilabel:`Edit` button in the window's top-right).  The
+empty HTML field now displays a big placeholder image, if you drop
+snippets in or write some content for one of the teaching assistants,
+you will see that other TA profiles are unaffected.
+
+A more complex model
+--------------------
+
+Up to now, we've been working with displaying and manipulating
+objects representing teaching assistants. It's a basic and
+simple concept, but not one which allows for much further
+diving into interesting tools of OpenERP. Thus, let's add a
+list of course lectures.
+
 .. calendar model
 .. demo data for events dates
 .. access & formatting
@@ -325,9 +445,15 @@ Administration and ERP Integration
    .. improve generated views
 .. create list & form views for events
 
+.. [#taprofile] the teaching assistants profile view ends up
+                broken for now, but don't worry we'll get
+                around to it
+
 .. _bootstrap: http://getbootstrap.com
 
-.. _converter patterns: http://werkzeug.pocoo.org/docs/routing/#rule-format
+.. _converter pattern:
+.. _converter patterns:
+    http://werkzeug.pocoo.org/docs/routing/#rule-format
 
 .. _templates: http://en.wikipedia.org/wiki/Web_template
 
index c0d15ab..e54bbbb 100644 (file)
@@ -7,3 +7,9 @@ url-pattern
 templates-basic
 website-dependency
 website-layoutify
+ta-model
+ta-data
+ta-view-fix
+ta-t-field
+ta-html-biography
+ta-template-biography
diff --git a/doc/howto/howto_website/ta-data b/doc/howto/howto_website/ta-data
new file mode 100644 (file)
index 0000000..c38eae4
--- /dev/null
@@ -0,0 +1,37 @@
+# HG changeset patch
+# Parent 94316d8049d7453cf70aff198b2d7ad1c04bf089
+
+diff --git a/__openerp__.py b/__openerp__.py
+--- a/__openerp__.py
++++ b/__openerp__.py
+@@ -5,5 +5,6 @@
+     'data': [
+         'ir.model.access.csv',
+         'views/templates.xml',
++        'data/teaching_assistants.xml',
+     ]
+ }
+diff --git a/data/teaching_assistants.xml b/data/teaching_assistants.xml
+new file mode 100644
+--- /dev/null
++++ b/data/teaching_assistants.xml
+@@ -0,0 +1,19 @@
++<openerp>
++    <data>
++        <record id="padilla" model="academy.tas">
++            <field name="name">Diana Padilla</field>
++        </record>
++        <record id="carroll" model="academy.tas">
++            <field name="name">Jody Carroll</field>
++        </record>
++        <record id="vaughn" model="academy.tas">
++            <field name="name">Lester Vaughn</field>
++        </record>
++        <record id="jimenez" model="academy.tas">
++            <field name="name">Paul Jimenez</field>
++        </record>
++        <record id="harris" model="academy.tas">
++            <field name="name">Tanya Harris</field>
++        </record>
++    </data>
++</openerp>
diff --git a/doc/howto/howto_website/ta-html-biography b/doc/howto/howto_website/ta-html-biography
new file mode 100644 (file)
index 0000000..5d9dbc0
--- /dev/null
@@ -0,0 +1,11 @@
+# HG changeset patch
+# Parent e603b52f5a0484822964f6cefd7e5b389d44399b
+diff --git a/models.py b/models.py
+--- a/models.py
++++ b/models.py
+@@ -7,4 +7,5 @@ class TeachingAssistants(orm.Model):
+     _columns = {
+         'name': fields.char(),
++        'biography': fields.html(),
+     }
diff --git a/doc/howto/howto_website/ta-model b/doc/howto/howto_website/ta-model
new file mode 100644 (file)
index 0000000..7b9917c
--- /dev/null
@@ -0,0 +1,68 @@
+# HG changeset patch
+# Parent 9735c655933b94f5e9017d0aac0b6e579f23adba
+
+diff --git a/__init__.py b/__init__.py
+--- a/__init__.py
++++ b/__init__.py
+@@ -1,1 +1,2 @@
+ import controllers
++import models
+diff --git a/__openerp__.py b/__openerp__.py
+--- a/__openerp__.py
++++ b/__openerp__.py
+@@ -3,6 +3,7 @@
+     'category': "Tools",
+     'depends': ['website'],
+     'data': [
++        'ir.model.access.csv',
+         'views/templates.xml',
+     ]
+ }
+diff --git a/controllers.py b/controllers.py
+--- a/controllers.py
++++ b/controllers.py
+@@ -1,19 +1,13 @@
+ from openerp import http
+ from openerp.addons.web.controllers import main
+-teaching_assistants = [
+-    {'name': "Diana Padilla"},
+-    {'name': "Jody Carroll"},
+-    {'name': "Lester Vaughn"},
+-    {'name': "Paul Jimenez"},
+-    {'name': "Tanya Harris"},
+-]
+-
+ class Home(main.Home):
+     @http.route('/', auth='public')
+     def index(self):
++        tas = http.request.registry['academy.tas'].search_read(
++            http.request.cr, http.request.uid, context=http.request.context)
+         return http.request.website.render('academy.index', {
+-            'tas': teaching_assistants,
++            'tas': tas,
+         })
+     @http.route('/tas/<int:id>/', auth='public', website=True)
+diff --git a/ir.model.access.csv b/ir.model.access.csv
+new file mode 100644
+--- /dev/null
++++ b/ir.model.access.csv
+@@ -0,0 +1,2 @@
++id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
++access_academy_tas,access_academy_tas,model_academy_tas,,1,0,0,0
+diff --git a/models.py b/models.py
+new file mode 100644
+--- /dev/null
++++ b/models.py
+@@ -0,0 +1,10 @@
++# -*- coding: utf-8 -*-
++
++from openerp.osv import orm, fields
++
++class TeachingAssistants(orm.Model):
++    _name = 'academy.tas'
++
++    _columns = {
++        'name': fields.char(),
++    }
diff --git a/doc/howto/howto_website/ta-t-field b/doc/howto/howto_website/ta-t-field
new file mode 100644 (file)
index 0000000..706850a
--- /dev/null
@@ -0,0 +1,14 @@
+# HG changeset patch
+# Parent e00d1176e7ba0a515a45874d9f9e8703722810d1
+diff --git a/views/templates.xml b/views/templates.xml
+--- a/views/templates.xml
++++ b/views/templates.xml
+@@ -35,7 +35,7 @@
+             <div class="oe_structure"/>
+             <div class="oe_structure">
+                 <div class="container">
+-                    <h1><t t-esc="ta.name"/></h1>
++                    <h1><t t-field="ta.name"/></h1>
+                 </div>
+             </div>
+             <div class="oe_structure"/>
diff --git a/doc/howto/howto_website/ta-template-biography b/doc/howto/howto_website/ta-template-biography
new file mode 100644 (file)
index 0000000..9f596fa
--- /dev/null
@@ -0,0 +1,16 @@
+# HG changeset patch
+# Parent bba1cb179e03ab82504d12accfe456633806ba06
+diff --git a/views/templates.xml b/views/templates.xml
+--- a/views/templates.xml
++++ b/views/templates.xml
+@@ -35,7 +35,9 @@
+             <div class="oe_structure"/>
+             <div class="oe_structure">
+                 <div class="container">
+-                    <h1><t t-field="ta.name"/></h1>
++                    <h1 t-field="ta.name"/>
++                    <h2>Biography</h2>
++                    <div t-field="ta.biography"/>
+                 </div>
+             </div>
+             <div class="oe_structure"/>
diff --git a/doc/howto/howto_website/ta-view-fix b/doc/howto/howto_website/ta-view-fix
new file mode 100644 (file)
index 0000000..88fcdef
--- /dev/null
@@ -0,0 +1,38 @@
+# HG changeset patch
+# Parent d757ab6e2223e63f283b31815c8ff650ea42e2e7
+diff --git a/controllers.py b/controllers.py
+--- a/controllers.py
++++ b/controllers.py
+@@ -10,6 +10,8 @@ class Home(main.Home):
+             'tas': tas,
+         })
+-    @http.route('/tas/<int:id>/', auth='public', website=True)
+-    def ta(self, id):
+-        return http.request.website.render('academy.ta', teaching_assistants[id])
++    @http.route('/tas/<model("academy.tas"):ta>/', auth='public', website=True)
++    def ta(self, ta):
++        return http.request.website.render('academy.ta', {
++            'ta': ta
++        })
+diff --git a/views/templates.xml b/views/templates.xml
+--- a/views/templates.xml
++++ b/views/templates.xml
+@@ -17,7 +17,7 @@
+                     <h2>Teaching Assistants</h2>
+                     <ul>
+                         <li t-foreach="tas" t-as="ta">
+-                            <a t-att-href="url_for('/tas/%d/' % ta_index)">
++                            <a t-att-href="url_for('/tas/%s/' % ta['id'])">
+                                 <t t-esc="ta['name']"/>
+                             </a>
+                         </li>
+@@ -35,7 +35,7 @@
+             <div class="oe_structure"/>
+             <div class="oe_structure">
+                 <div class="container">
+-                    <h1><t t-esc="name"/></h1>
++                    <h1><t t-esc="ta.name"/></h1>
+                 </div>
+             </div>
+             <div class="oe_structure"/>
index f3bd6ba..27cfd6d 100644 (file)
@@ -1,10 +1,10 @@
 # HG changeset patch
-# Parent c7be40a51aa39a1562ad0d8e3f75e56ca4ab47fc
+# Parent 375b20994a7069eadfbd64c793328a07f7d9baf6
 
 diff --git a/views/templates.xml b/views/templates.xml
 --- a/views/templates.xml
 +++ b/views/templates.xml
-@@ -1,42 +1,42 @@
+@@ -1,42 +1,46 @@
  <openerp>
      <data>
  <template id="academy.index" name="Index">
@@ -72,9 +72,13 @@ diff --git a/views/templates.xml b/views/templates.xml
 -    </html>
 +    <t t-call="website.layout">
 +        <div id="wrap">
-+            <div class="container">
-+                <h1><t t-esc="name"/></h1>
++            <div class="oe_structure"/>
++            <div class="oe_structure">
++                <div class="container">
++                    <h1><t t-esc="name"/></h1>
++                </div>
 +            </div>
++            <div class="oe_structure"/>
 +        </div>
 +    </t>
  </template>