免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5631 | 回复: 0
打印 上一主题 下一主题

upload文档 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-07-28 17:25 |只看该作者 |倒序浏览



Search:      


Wiki Navigation

File Upload Tutorial
¶
TurboGears
0.8a3
This is a follow up to the existing 20 minute wiki:
http://turbogears.org/docs/wiki20/index.html
. At this point, it is assumed that you have:

  • installed TG
  • completed the previous tutorial
  • are ready to add to that tutorial

Here is what this tutorial is all about: File Uploads. After completing the above tutorial, I thought, 'gee, it'd be cool if I could upload files to the wiki'. And the way things go, one thing leads to another, and I wanted to download them, too. This introduces some issues, like:

  • ui for displaying the files (we'll use templates for all the common stuff)
  • ui for uploading/downloading the files
  • state issues : we don't want to upload a file to a page that doesn't exist yet

Rather than stepwise you thru my thought process and re-build this app like a real tutorial, I'll present the major issues along with the major chunks of code to address them.
BTW - you don't have to copy and paste from this page, there are zip files attached...just grab the real thing, amigo.
-Todd
Update the DB Tables
¶
We need to update the database to add a new table, the uploaded files table. This is a many to many relationship in my example. We'll have to drop our old tables and re-create these for the relationships to match. Here we go:
  • stop the server
  • drop the existing tables

    • tg-admin sql drop page
    • tg-admin sql drop uploadedfile

  • your new model.py from sqlobject import *
    from turbogears.database import PackageHub
    hub = PackageHub("toddswiki")
    __connection__ = hub
    # class YourDataClass(SQLObject):
    #     pass
    class Page(SQLObject):
            pagename = StringCol(alternateID=True, length=30)
            data = StringCol()
            attached_files = RelatedJoin('UploadedFile')
    class UploadedFile(SQLObject):
            filename = StringCol(alternateID=True, length=100)
            abspath = StringCol()
            size = IntCol()
            referenced_in_pages = RelatedJoin('Page')
  • create the new tables

    • tg-admin sql create

    Add the 'upload' Method
    ¶
    Here is the meat and potatoes. We add the upload method and a bunch of state logic. The idea is simple: we want to upload files and have them relate to a page. If a user uploads a previously uploaded file, we skip the upload, but we add the relationship to the db. So, multiple pages can reference a single uploaded file. And a single page can reference many files. Let's store these files in an app configured location:
  • Add upload directory to the cfg file
    #def.cfg
    [global]
    # Upload dir
    wiki.uploads="./uploads"
  • Add upload dir check to controller, create it if nec.
    #controller.py
    #default upload dir to ./uploads
    UPLOAD_DIR = cherrypy.config.get("wiki.uploads", os.path.join(os.getcwd(),"uploads"))
    if not os.path.exists(UPLOAD_DIR):
        os.makedirs(UPLOAD_DIR)
  • Add the 'upload' method (remember meat and potatoes)
    #controller.py
            @turbogears.expose()
            def upload(self, upload_file, pagename, new, **keywords):
                    try:
                            p = Page.byPagename(pagename)
                    except SQLObjectNotFound:
                            turbogears.flash("Must save page first")
                            raise cherrypy.HTTPRedirect(turbogears.url("/%s" % pagename))
                   
                    data = upload_file.file.read()
                    target_file_name = os.path.join(os.getcwd(),UPLOAD_DIR,upload_file.filename)
                    try:
                            u =  UploadedFile.byFilename(upload_file.filename)
                            turbogears.flash("File already uploaded: %s is already at %s" %  (upload_file.filename, target_file_name))
                    except SQLObjectNotFound:
                            f = open(target_file_name, 'w')
                            f.write(data)
                            f.close()
                            turbogears.flash("File uploaded successfully: %s saved as : %s" % (upload_file.filename, target_file_name))
                            u = UploadedFile(filename=upload_file.filename, abspath=target_file_name, size=0)
                           
                    Page.byPagename(pagename).addUploadedFile(u)
                    raise cherrypy.HTTPRedirect(turbogears.url("/%s" % pagename))
  • Note: the above uses the db to determine the page state. If the page doesn't exist in the db, then we cannot relate an uploaded file to it:                 try:
                            p = Page.byPagename(pagename)
                    except SQLObjectNotFound:
                            turbogears.flash("Must save page first")
                            raise cherrypy.HTTPRedirect(turbogears.url("/%s" % pagename))
    Add 'upload' to the page.kid
    ¶
  • Here's the form that calls the upload method (note we use a 'post'). Pretty simple. I have the hidden variable 'new' in here b/c I was going to use that for state tracking in the same way that the original tutorial did. For some reason, this wasn't working for me so I use the database instead, see above comment.
    #page.kid
           
                   
                   
                    filename:
                   
           
    Add the goo to display the file listings
    ¶
  • Here is the code:        
                    Attached Files:
                    Filenamehere.
           
  • Add this code to page.kid and edit.kid
  • I've appended to this tutorial my notes for generalizing this with templates (see below)
    Add the 'download' method
    ¶
  • cherrypy.lib.cptools.serveFile makes this super simple:
    #controller.py
            @turbogears.expose()
            def download(self, filename):
                    uf = UploadedFile.byFilename(filename)
                    return cherrypy.lib.cptools.serveFile(uf.abspath, "application/x-download", "attachment", uf.filename)
    Add error handling to the index method, just in case publish parts barfs
    ¶
    #controller.py
            @turbogears.expose(html="toddswiki.templates.page")
            def index(self, pagename="FrontPage"):
                    try:
                            page = Page.byPagename(pagename)
                            uploads = [item.filename for item in page.attached_files]
                    except SQLObjectNotFound:
                            raise cherrypy.HTTPRedirect(turbogears.url("/notfound",pagename=pagename))
                    try:
                            content = publish_parts(page.data, writer_name="html")["html_body"]
                    except:
                            content = page.data
                    root = str(turbogears.url("/"))
                    content = wikiwords.sub(r'\1' % root, content)
                    content = content.encode("utf8")
                    return dict(data=content, pagename=page.pagename, uploads=uploads)
    Generalize the File listing with Kid Templates (inheritance/matching)
    ¶
    Make the following changes to get this working:
    #master.kid
    #page.kid / edit.kid
            
    #includes.kid
                    Attached Files:
                    Filenamehere.

    For more details, see:

    Attachments
    wiki.zip
    (30.4 kB) -full files for the
    FileUploadTutorial
    , added by GreenTea  on 10/20/05 18:14:28.
    Download in other formats:



    Powered by
    Trac 0.9.4
    By
    Edgewall Software
    .
    Visit the Trac open source project at
    http://trac.edgewall.com/



    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/3176/showart_147038.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP