Anonymous avatar Anonymous committed 1949ba3

Docs.

Comments (0)

Files changed (5)

 
 * Incorporate Ian's ChoiceBackend.
 
-kay.sessions
-------------
-
-* Implement lazy loading session data(as well as request.user)
-
 kay.utils.forms
 ---------------
 

docs/japanese/source/generic_views.rst

 
   この機能はまだ実験段階です。将来仕様が変わる可能性があります。
 
-概要
-----
+CRUD
+====
+
+CRUD 概要
+---------
 
 ``kay.generics.crud.CRUDViewGroup`` を使用すると、汎用的な CRUD の
 view を簡単に定義できます。CRUDViewGroup を使用するには、モデル・モデル
 フォーム・テンプレートさえあれば良いです。
 
-
 簡単な例
 --------
 
      authorize = only_owner_can_write_except_for_admin
 
 TODO: ``authorize`` メソッドに関する詳細な説明
+
+
+RESTfull API
+============
+
+RESTfull API 概要
+-----------------
+
+You can use ``kay.generics.rest.RESTViewGroup`` in order to create
+RESTfull APIs easily. You can create various handlers for RESTfull
+services of specified models.
+
+Your first REST
+---------------
+
+Let's see a simple example.
+
+myapp/models.py:
+
+.. code-block:: python
+
+   # -*- coding: utf-8 -*-
+   # myapp.models
+
+   from google.appengine.ext import db
+
+   # Create your models here.
+
+   class MyModel(db.Model):
+     comment = db.StringProperty()
+     created = db.DateTimeProperty(auto_now_add=True)
+
+Its a simple model for just storing comments. You can create RESTfull
+view groups as follows:
+
+myapp/urls.py:
+
+.. code-block:: python
+
+   # -*- coding: utf-8 -*-
+   # myapp.urls
+   # 
+
+   from kay.routing import (
+     ViewGroup, Rule
+   )
+
+   from kay.generics.rest import RESTViewGroup
+
+   class MyRESTViewGroup(RESTViewGroup):
+     models = ['myapp.models.MyModel']
+
+   view_groups = [
+     MyRESTViewGroup(),
+     ViewGroup(
+       Rule('/', endpoint='index', view='myapp.views.index'),
+     )
+   ]
+
+
+This will give you following Method/URL combinations for RESTfull
+access to this model, assuming that myapp is mounted at '/'. All the
+<typeName> in the example bellow is 'MyModel' in this case.
+
+* GET http://yourdomain.example.com/rest/metadata
+
+  * Gets all known types
+
+* GET http://yourdomain.example.com/rest/metadata/<typeName>
+
+  * Gets the <typeName> type profile (as XML Schema). (If the model is
+    an Expando model, the schema will include an "any" element).
+
+* GET http://yourdomain.example.com/rest/<typeName>
+
+  * Gets the first page of <typeName> instances (number returned per
+    page is defined by server). The returned list element will contain
+    an "offset" attribute. If it has a value, that is the next offset
+    to use to retrieve more results. If it is empty, there are no more
+    results.
+
+* GET http://yourdomain.example.com/rest/<typeName>?offset=50
+
+  * Gets the page of <typeName> instances starting at offset 50 (0
+    based numbering). The offset should generally be filled in from a
+    previous request.
+
+* GET http://yourdomain.example.com/rest/<typeName>?<queryTerm>[&<queryTerm>]
+
+  * Gets a page of <typeName> instances using a query filter created
+    from the given query terms (with offset features mentioned above).
+    Multiple query terms will be AND'ed together to create the filter.
+    A query filter term has the structure:
+    f<op>_<propertyName>=<value>
+
+    Examples:
+
+    * "feq_author=bob@example.com" means include instances where the
+      value of the "author" property is equal to "bob@example.com"
+
+    * "flt_count=37&fin_content=value1,value2" means include instances
+      where the value of the "count" property greater than "37" and
+      the value of the content property is "value1" or "value2"
+
+    Available operations:
+
+    * ``feq_`` -> "equal to"
+    * ``flt_`` -> "less than"
+    * ``fgt_`` -> "greater than"
+    * ``fle_`` -> "less than or equal to"
+    * ``fge_`` -> "greater than or equal to"
+    * ``fne_`` -> "not equal to"
+    * ``fin_`` -> "in <commaSeparatedList>"
+    * ``order=param_name`` will make result set to be ordered
+
+    Blob and Text properties may not be used in a query filter
+
+* GET http://yourdomain.example.com/rest/<typeName>/<key>
+
+  * Gets the single <typeName> instance with the given <key>
+
+* POST http://yourdomain.example.com/rest/<typeName>
+
+  * Create new <typeName> instance using the posted data which should
+    adhere to the XML Schema for the type
+
+  * Returns the key of the new instance by default. With "?type=full"
+    at the end of the url, returns the entire updated instance like a
+    GET request.
+
+* POST http://yourdomain.example.com/rest/<typeName>/<key>
+
+  * Partial update of the existing <typeName> instance with the given
+    <key>. Will only modify fields included in the posted xml
+    data. (Returns same as previous request)
+
+* PUT http://<service>/rest/<typeName>/<key>
+
+  * Complete replacement of the existing <typeName> instance with the
+    given <key>(Returns same as previous request)
+
+* DELETE http://<service>/rest/<typeName>/<key>
+
+  * Delete the existing <typeName> instance
+
+By default, you need to create XML elements as the payload for POST
+and PUT requests, but you can also use json payload by setting
+"Content-Type" request header to "application/json".
+
+By default, the result set is served in XML format, but you can also
+get json response by setting "Accept" request header to
+"application/json" as well.
+
+
+Ajax example
+------------
+
+Here is an example for guestbook implementation with using jquery's
+ajax request.
+
+myapp/templates/index.html:
+
+.. code-block:: html
+
+   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+   <html>
+   <head>
+   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+   <title>Top Page - myapp</title>
+   <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
+   <script type="text/javascript">
+   function deleteEntity(key) {
+     $.ajax({
+       type: "DELETE",
+       url: "/rest/MyModel/"+key,
+       success: function(data) {
+	 refreshData();
+       }
+     });
+   }
+   function displayEntity(entity) {
+     $("#comments").append(entity.comment+
+       "<i> at " + entity.created + "</i>"+
+       '&nbsp;<a href="#" onclick="deleteEntity(\''+entity.key+'\');">x</a><br>');
+   }
+   function refreshData() {
+     $.ajax({
+       type: "GET",
+       url: "/rest/MyModel?ordering=-created",
+       dataType: "json",
+       success: function(data) {
+	 $("#comments").html("");
+	 if (data.list.MyModel) {
+	   if (data.list.MyModel.key) {
+	     displayEntity(data.list.MyModel);
+	   } else {
+	     for (var i=0; i < data.list.MyModel.length; i++) {
+	       displayEntity(data.list.MyModel[i]);
+	     }
+	   }
+	 }
+       }
+     });
+     $("#comment").focus();
+   }
+   function sendData() {
+     $("#sendButton").attr("disabled", "disabled");
+     $.ajax({
+       type: "POST",
+       url: "/rest/MyModel?type=full",
+       dataType: "json",
+       contentType: "application/json",
+       data: JSON.stringify({"MyModel": {"comment": $("#comment").val()}}),
+       success: function(data) {
+	 $("#comment").val("");
+	 $("#sendButton").attr("disabled", "");
+	 refreshData();
+       }
+     });
+   }
+   $(document).ready(function(){
+     $("#comment").keypress(function(e) {
+       if (e.which == 13) {
+	 sendData();
+       }
+     });
+     refreshData();
+   });
+   </script>
+   </head>
+   <body>
+   <input type="text" id="comment">
+   <input type="button" onclick="sendData();" value="send" id="sendButton">
+   <div id="comments"></div>
+   </body>
+   </html>

docs/japanese/source/tutorial.rst

 
    class Comment(db.Model):
      user = kay.db.OwnerProperty()
-     category = db.ReferenceProperty(Category)
+     category = db.ReferenceProperty(Category, collection_name='comments')
      body = db.StringProperty(required=True, verbose_name=u'Your Comment')
      created = db.DateTimeProperty(auto_now_add=True)
 

docs/source/generic_views.rst

    This feature is still an experimental. The implementation might
    change in the future.
 
-Overview
---------
+CRUD
+====
+
+CRUD Overview
+-------------
 
 You can use ``kay.generics.crud.CRUDViewGroup`` in order to define
 generic CRUD views easily. You just need your own model, modelform
      authorize = only_owner_can_write_except_for_admin
 
 TODO: detailed docs about ``authorize`` method.
+
+
+RESTfull API
+============
+
+RESTfull API overview
+---------------------
+
+You can use ``kay.generics.rest.RESTViewGroup`` in order to create
+RESTfull APIs easily. You can create various handlers for RESTfull
+services of specified models.
+
+Your first REST
+---------------
+
+Let's see a simple example.
+
+myapp/models.py:
+
+.. code-block:: python
+
+   # -*- coding: utf-8 -*-
+   # myapp.models
+
+   from google.appengine.ext import db
+
+   # Create your models here.
+
+   class MyModel(db.Model):
+     comment = db.StringProperty()
+     created = db.DateTimeProperty(auto_now_add=True)
+
+Its a simple model for just storing comments. You can create RESTfull
+view groups as follows:
+
+myapp/urls.py:
+
+.. code-block:: python
+
+   # -*- coding: utf-8 -*-
+   # myapp.urls
+   # 
+
+   from kay.routing import (
+     ViewGroup, Rule
+   )
+
+   from kay.generics.rest import RESTViewGroup
+
+   class MyRESTViewGroup(RESTViewGroup):
+     models = ['myapp.models.MyModel']
+
+   view_groups = [
+     MyRESTViewGroup(),
+     ViewGroup(
+       Rule('/', endpoint='index', view='myapp.views.index'),
+     )
+   ]
+
+
+This will give you following Method/URL combinations for RESTfull
+access to this model, assuming that myapp is mounted at '/'. All the
+<typeName> in the example bellow is 'MyModel' in this case.
+
+* GET http://yourdomain.example.com/rest/metadata
+
+  * Gets all known types
+
+* GET http://yourdomain.example.com/rest/metadata/<typeName>
+
+  * Gets the <typeName> type profile (as XML Schema). (If the model is
+    an Expando model, the schema will include an "any" element).
+
+* GET http://yourdomain.example.com/rest/<typeName>
+
+  * Gets the first page of <typeName> instances (number returned per
+    page is defined by server). The returned list element will contain
+    an "offset" attribute. If it has a value, that is the next offset
+    to use to retrieve more results. If it is empty, there are no more
+    results.
+
+* GET http://yourdomain.example.com/rest/<typeName>?offset=50
+
+  * Gets the page of <typeName> instances starting at offset 50 (0
+    based numbering). The offset should generally be filled in from a
+    previous request.
+
+* GET http://yourdomain.example.com/rest/<typeName>?<queryTerm>[&<queryTerm>]
+
+  * Gets a page of <typeName> instances using a query filter created
+    from the given query terms (with offset features mentioned above).
+    Multiple query terms will be AND'ed together to create the filter.
+    A query filter term has the structure:
+    f<op>_<propertyName>=<value>
+
+    Examples:
+
+    * "feq_author=bob@example.com" means include instances where the
+      value of the "author" property is equal to "bob@example.com"
+
+    * "flt_count=37&fin_content=value1,value2" means include instances
+      where the value of the "count" property greater than "37" and
+      the value of the content property is "value1" or "value2"
+
+    Available operations:
+
+    * ``feq_`` -> "equal to"
+    * ``flt_`` -> "less than"
+    * ``fgt_`` -> "greater than"
+    * ``fle_`` -> "less than or equal to"
+    * ``fge_`` -> "greater than or equal to"
+    * ``fne_`` -> "not equal to"
+    * ``fin_`` -> "in <commaSeparatedList>"
+    * ``order=param_name`` will make result set to be ordered
+
+    Blob and Text properties may not be used in a query filter
+
+* GET http://yourdomain.example.com/rest/<typeName>/<key>
+
+  * Gets the single <typeName> instance with the given <key>
+
+* POST http://yourdomain.example.com/rest/<typeName>
+
+  * Create new <typeName> instance using the posted data which should
+    adhere to the XML Schema for the type
+
+  * Returns the key of the new instance by default. With "?type=full"
+    at the end of the url, returns the entire updated instance like a
+    GET request.
+
+* POST http://yourdomain.example.com/rest/<typeName>/<key>
+
+  * Partial update of the existing <typeName> instance with the given
+    <key>. Will only modify fields included in the posted xml
+    data. (Returns same as previous request)
+
+* PUT http://<service>/rest/<typeName>/<key>
+
+  * Complete replacement of the existing <typeName> instance with the
+    given <key>(Returns same as previous request)
+
+* DELETE http://<service>/rest/<typeName>/<key>
+
+  * Delete the existing <typeName> instance
+
+By default, you need to create XML elements as the payload for POST
+and PUT requests, but you can also use json payload by setting
+"Content-Type" request header to "application/json".
+
+By default, the result set is served in XML format, but you can also
+get json response by setting "Accept" request header to
+"application/json" as well.
+
+
+Ajax example
+------------
+
+Here is an example for guestbook implementation with using jquery's
+ajax request.
+
+myapp/templates/index.html:
+
+.. code-block:: html
+
+   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+   <html>
+   <head>
+   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+   <title>Top Page - myapp</title>
+   <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
+   <script type="text/javascript">
+   function deleteEntity(key) {
+     $.ajax({
+       type: "DELETE",
+       url: "/rest/MyModel/"+key,
+       success: function(data) {
+	 refreshData();
+       }
+     });
+   }
+   function displayEntity(entity) {
+     $("#comments").append(entity.comment+
+       "<i> at " + entity.created + "</i>"+
+       '&nbsp;<a href="#" onclick="deleteEntity(\''+entity.key+'\');">x</a><br>');
+   }
+   function refreshData() {
+     $.ajax({
+       type: "GET",
+       url: "/rest/MyModel?ordering=-created",
+       dataType: "json",
+       success: function(data) {
+	 $("#comments").html("");
+	 if (data.list.MyModel) {
+	   if (data.list.MyModel.key) {
+	     displayEntity(data.list.MyModel);
+	   } else {
+	     for (var i=0; i < data.list.MyModel.length; i++) {
+	       displayEntity(data.list.MyModel[i]);
+	     }
+	   }
+	 }
+       }
+     });
+     $("#comment").focus();
+   }
+   function sendData() {
+     $("#sendButton").attr("disabled", "disabled");
+     $.ajax({
+       type: "POST",
+       url: "/rest/MyModel?type=full",
+       dataType: "json",
+       contentType: "application/json",
+       data: JSON.stringify({"MyModel": {"comment": $("#comment").val()}}),
+       success: function(data) {
+	 $("#comment").val("");
+	 $("#sendButton").attr("disabled", "");
+	 refreshData();
+       }
+     });
+   }
+   $(document).ready(function(){
+     $("#comment").keypress(function(e) {
+       if (e.which == 13) {
+	 sendData();
+       }
+     });
+     refreshData();
+   });
+   </script>
+   </head>
+   <body>
+   <input type="text" id="comment">
+   <input type="button" onclick="sendData();" value="send" id="sendButton">
+   <div id="comments"></div>
+   </body>
+   </html>

docs/source/tutorial.rst

 
    class Comment(db.Model):
      user = kay.db.OwnerProperty()
-     category = db.ReferenceProperty(Category)
+     category = db.ReferenceProperty(Category, collection_name='comments')
      body = db.StringProperty(required=True, verbose_name=u'Your Comment')
      created = db.DateTimeProperty(auto_now_add=True)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.