I have a multi-tenant application, where users can upload files. I save 
these in a different directory for each client (tenant), so I can keep tabs 
on the overall disk space and number of files uploaded by each.

This works fine when the table is defined in a model file - from the view I 
can download existing files and upload new ones:

Model:
from gluon import *
import os
client_id=3 #hard coded here for illustration
           
db.define_table('attachment_model',
    Field('attached_file', 'upload', label="Upload new file", 
          uploadfolder=os.path.join(request.folder, 'uploads', str(client_id
), 'attachments'),
          requires=IS_NOT_EMPTY(), autodelete=True),
    Field('filename', type='string', length=150, writable=False),
    migrate=True)

Controller:
def model_based():
    db.attachment_model.filename.readable=False
    form_attachment=SQLFORM(db.attachment_model,
                 autodelete=True, labels=None, deletable=True,
                 fields=['attached_file'], submit_button='Attach file')
    if hasattr(request.vars.attached_file, "filename"):
        #save original file name
        form_attachment.vars.filename=request.vars.attached_file.filename
    if form_attachment.process().accepted:
        response.flash = 'attachment saved'
    elif form_attachment.errors:
        response.flash = 'form has errors'
    # list existing attachments
    rows=db(db.attachment_model.id>0).select()
    response.view = 'attachment.html'
    return dict(form_attachment=form_attachment,
                rows=rows)

View:
{{extend 'layout.html'}}
<h1>
    Attached files
</h1>
    <table class="table-striped">
        <thead>
            <tr>
                <td>id</td>
                <td>filename</td>
            </tr>
        </thead>
        <tbody>
            {{for r in rows:}}
                <tr>
                    <td>{{=r.id}}</td>
                    <td>{{=A(r.filename, _href=URL('download', args=(str(
client_id) + '/attachments/' + r['attached_file'])))}}</td>
                </tr>
            {{pass}}
        </tbody>
    </table>
    
<h2>Add new attachment</h2>
<div class="form-inline well">
    {{=form_attachment}}
</div>

My issue is when I re-write the above so the model definition is moved to a 
module.

Module mod_attachment.py:
from gluon import *
import os

class Attachment_module(object):
    def __init__(self, db):
        self.db = db

    def define_tables(self):
        db = self.db
        client_id=3
        if not 'attachment_module' in db.tables:
            db.define_table('attachment_module',
                Field('attached_file', 'upload', label="Upload new file", 
                      uploadfolder=os.path.join(current.request.folder, 
'uploads', str(client_id), 'attachments'), 
                      requires=IS_NOT_EMPTY(), autodelete=True),
                Field('filename', type='string', length=150, writable=False
),
                Field('request_tenant', type='integer', default=client_id,
                      readable=False, writable=False),
                migrate=True)

Revised controller:
def module_based():
    from mod_attachment import Attachment_module
    attachment_module = Attachment_module(db) 
    attachment_module.define_tables()
    db.attachment_module.filename.readable=False
    form_attachment=SQLFORM(db.attachment_module,
                 autodelete=True, labels=None, deletable=True,
                 fields=['attached_file'], submit_button='Attach file')
    if hasattr(request.vars.attached_file, "filename"):
        #save original file name
        form_attachment.vars.filename=request.vars.attached_file.filename
    if form_attachment.process().accepted:
        response.flash = 'attachment saved'
    elif form_attachment.errors:
        response.flash = 'form has errors'
    # list existing attachments
    rows=db(db.attachment_module.id>0).select()
    response.view = 'attachment.html'
    return dict(form_attachment=form_attachment,
                rows=rows)

With this approach, I can still list the uploaded files and add additional 
ones (using the same view as before), but the download function no longer 
works.

So my question is why not? Do I have to modify the standard download 
function, and how?
Hope these are not daft questions - any pointers would be appreciated.

Andy






-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to