Anonymous avatar Anonymous committed 0cbdd9d

addition of file upload docs.

Comments (0)

Files changed (15)

 *.pyc
 docs/_static/ToscaWidgetsFormsExample.zip
 docs/_static/Wiki20_final.zip
+docs/project_code/tosca_forms/ToscaSample.egg-info
+docs/project_code/tosca_forms/toscasample/public/movies/
+docs/project_code/tosca_forms/devdata.db
 *~

docs/main/FormBasics.rst

         genre_id = Column(Integer, ForeignKey('genres.genre_id'))
         genre = relation('Genre', backref='movies')
         release_date = Column(Date, nullable=True)
+
     
     class Director(DeclarativeBase):
         __tablename__ = "directors"

docs/main/ToscaWidgets/forms.rst

 
 .. image:: images/movie_form_5.png
 
+
+Adding a File Upload
+----------------------
+
+Now let's add a file upload to see how that works.  We will add a new
+file field to our form, and then on the serverside we will gather
+the data from the file form and save it to a file in the public directory
+on the server.  This file could later be served up and displayed on our
+movie page.
+
+The first thing we need to do is add the file field to our form.  
+First, add ``FileField`` to our import::
+
+    from tw.forms import (TableForm, CalendarDatePicker,
+        SingleSelectField, Spacer, TextField, TextArea, FileField)
+
+Then, add the field to the ``fields`` parameter of our widget::
+
+        FileField('picture_filename',
+            help_text = 'Please provide a picture for this movie.'),
+        Spacer()
+
+Our form now looks like this:
+
+.. image:: images/movie_form_7.png
+
+
+Now, if you look at the source for your page you will see that the enctype
+has changed in our form.::
+
+   <form id="create_movie_form" action="create" method="post" class="required movieform" enctype="multipart/form-data">
+
+If you happen to be looking at this reference for pointers on how to 
+upload files, then this is important to note if you are not using
+ToscaWidgets.  ``enctype="multipart/form-data"`` is needed in order
+to tell the web server that the form contains a multipart message,
+including a file to upload.
+
+Now we can modify our create method to save our new file to the public directory,
+noting the filename in the database.  First, we need to locate our public directory:
+
+.. code:: tosca_forms/toscasample/controllers/root.py
+  :section: picture_import
+
+Then we change the create code to save our filename to the database and our file to
+the public directory.
+
+.. code:: tosca_forms/toscasample/controllers/root.py
+  :section: create_with_picture
+
+Now if you check the public directory after an insert you will see
+the file has been written.  This file could be used in the listing
+or display of the movie information, since it has been placed
+in the public directory.
+
+
 More Form Fields
 ----------------
 
 .. _ToscaWidgets: http://toscawidgets.org
 .. _`available form fields`: http://toscawidgets.org/documentation/tw.forms/modules/fields/
 
+
 Form Validation
 ---------------
 
 You can also build `compound validators`_ (schemas) corresponding to
 fieldsets or whole forms.
 
+
+
 .. _FormEncode: http://www.formencode.org
 .. _`available validators`: http://formencode.org/module-formencode.validators.html
 .. _`compound validators`: http://www.formencode.org/Validator.html#compound-validators
Add a comment to this file

docs/main/ToscaWidgets/images/movie_form_7.png

Added
New image
 
 .. todo:: Difficulty: Medium. make sure that override_template is more visible, and provide a tutorial on how to use it
 
-.. todo:: Difficulty: Medium. port http://docs.turbogears.org/1.0/FileUploadTutorial to TG2, why not just release it as a project tgext.upload?
-.. todo:: Difficulty: Medium. Include these docs: http://groups.google.com/group/turbogears/browse_thread/thread/6b44420129281259 How to upload picture or video in Turbogears
 .. todo:: Difficulty: Medium. Incorporate these docs: http://groups.google.com/group/turbogears/browse_frm/thread/33a64a06ee4020ce?hl=en Upload images to a TG2 app with Dojo (Ajax style)
 
 .. todo:: Difficulty: Medium. add in notes regarding how to use repoze.who's user_checker

docs/project_code/tosca_forms/toscasample/controllers/root.py

 ##{import}
 from tg import tmpl_context, redirect, validate
 from toscasample.model import metadata, DBSession, Movie
-from toscasample.widgets.movie_form_6 import create_movie_form
+from toscasample.widgets.movie_form_7 import create_movie_form
 ##
 
+##{picture_import}
+
+import shutil
+import os
+from pkg_resources import resource_filename
+
+public_dirname = os.path.join(os.path.abspath(resource_filename('toscasample', 'public')))
+movies_dirname = os.path.join(public_dirname, 'movies')
+
+##
 class RootController(BaseController):
     error = ErrorController()
 
     def new(self, **kw):
         """Show form to add new movie data record."""
         tmpl_context.form = create_movie_form
-        return dict(modelname='Movie',
-            page='ToscaSample New Movie')
+        return dict(modelname='Movie', value=kw)
     ##
 
     ##{create}
         flash("Movie was successfully created.")
         redirect("list")
     ##
+
+    
+    ##{create_with_picture}
+    @validate(create_movie_form, error_handler=new)
+    @expose()
+    def create(self, **kw):
+        movie = Movie()
+        movie.title = kw['title']
+        movie.year = kw['year']
+        movie.release_date = kw['release_date']
+        movie.description = kw['description']
+        movie.genre = kw['genre']
+        
+        #save the filename to the database
+        movie.picture_filename = kw['picture_filename'].filename
+        DBSession.add(movie)
+        DBSession.flush()
+
+        #write the picture file to the public directory
+        movie_path = os.path.join(movies_dirname, str(movie.id))
+        try:
+            os.makedirs(movie_path)
+        except OSError:
+            #ignore if the folder already exists
+            pass
+            
+        movie_path = os.path.join(movie_path, movie.picture_filename)
+        f = file(movie_path, "w")
+        f.write(kw['picture_filename'].value)
+        f.close()
+        
+        flash("Movie was successfully created.")
+        redirect("list")

docs/project_code/tosca_forms/toscasample/model/movie.py

     year = Column(Integer, nullable=True)
     genre = Column(Integer, nullable=True)
     release_date = Column(Date, nullable=True)
+    picture_filename = Column(u'picture_filename', String)
+
 
     def __str__(self):
         if self.year:

docs/project_code/tosca_forms/toscasample/templates/new_form.html

 
 <h1>New ${modelname}</h1>
 
-<div py:replace="tmpl_context.form()">Input Form</div>
+<div py:replace="tmpl_context.form(value)">Input Form</div>
 
 </body>
 </html>

docs/project_code/tosca_forms/toscasample/widgets/movie_form_1.py

         title = TextField()
         year = TextField()
         release_date = CalendarDatePicker()
-        genre_options = enumerate((
+        genre_options = [x for x in enumerate((
             'Action & Adventure', 'Animation', 'Comedy',
-            'Documentary', 'Drama', 'Sci-Fi & Fantasy'))
+            'Documentary', 'Drama', 'Sci-Fi & Fantasy'))]
         genre = SingleSelectField(options=genre_options)
         description = TextArea()
 

docs/project_code/tosca_forms/toscasample/widgets/movie_form_2.py

 
 class MovieForm(TableForm):
 
-    genre_options = enumerate((
+    genre_options = [x for x in enumerate((
         'Action & Adventure', 'Animation', 'Comedy',
-        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))
+        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))]
 
     fields = [
         TextField('title', label_text='Movie Title'),

docs/project_code/tosca_forms/toscasample/widgets/movie_form_3.py

 
 class MovieForm(TableForm):
 
-    genre_options = enumerate((
+    genre_options = [x for x in enumerate((
         'Action & Adventure', 'Animation', 'Comedy',
-        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))
+        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))]
 
     fields = [
         TextField('title', label_text='Movie Title',

docs/project_code/tosca_forms/toscasample/widgets/movie_form_4.py

 
     hover_help = True
 
-    genre_options = enumerate((
+    genre_options = [x for x in enumerate((
         'Action & Adventure', 'Animation', 'Comedy',
-        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))
+        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))]
 
     fields = [
         TextField('title', label_text='Movie Title',

docs/project_code/tosca_forms/toscasample/widgets/movie_form_5.py

     template = "toscasample.widgets.templates.table_form"
     css = [CSSLink(link=url('/css/tooltips.css'))]
 
-    genre_options = enumerate((
+    genre_options = [x for x in enumerate((
         'Action & Adventure', 'Animation', 'Comedy',
-        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))
+        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))]
 
     fields = [
         TextField('title', label_text='Movie Title',

docs/project_code/tosca_forms/toscasample/widgets/movie_form_6.py

     css = [CSSLink(link=url('/css/tooltips.css'))]
     show_errors = True
 
-    genre_options = enumerate((
+    genre_options = [x for x in enumerate((
         'Action & Adventure', 'Animation', 'Comedy',
-        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))
+        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))]
 
     fields = [
         TextField('title', validator=NotEmpty,

docs/project_code/tosca_forms/toscasample/widgets/movie_form_7.py

+"""Movie Form"""
+
+from tw.api import CSSLink
+from tw.forms import (TableForm, CalendarDatePicker,
+    SingleSelectField, Spacer, TextField, TextArea, FileField)
+from tw.forms.validators import Int, NotEmpty, DateConverter
+from tg import url
+
+class MovieForm(TableForm):
+
+    template = "toscasample.widgets.templates.table_form"
+    css = [CSSLink(link=url('/css/tooltips.css'))]
+    show_errors = True
+    genre_options = [x for x in enumerate((
+        'Action & Adventure', 'Animation', 'Comedy',
+        'Documentary', 'Drama', 'Sci-Fi & Fantasy'))]
+
+    fields = [
+        TextField('title', validator=NotEmpty,
+            label_text='Movie Title',
+            help_text='Please enter the full title of the movie.'),
+        Spacer(),
+        TextField('year', validator=Int(min=1900, max=2100), size=4,
+            help_text='Please enter the year this movie was made.'),
+        CalendarDatePicker('release_date', validator=DateConverter(),
+            help_text='Please pick the exact release date.'),
+        SingleSelectField('genre', options=genre_options,
+            help_text = 'Please choose the genre of the movie.'),
+        Spacer(),
+        TextArea('description', attrs=dict(rows=3, cols=25),
+            help_text = 'Please provide a short description of the plot.'),
+        Spacer(),
+        FileField('picture_filename',
+            help_text = 'Please provide a picture for this movie.'),
+        Spacer()
+
+    ]
+
+    submit_text = 'Save Movie'
+
+
+create_movie_form = MovieForm("create_movie_form",  action='create')
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.