--
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+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
By default, all uploaded files handled by SQLFORMs are safely renamed and stored in the filesystem under the "uploads" folder. It is possible to instruct web2py to store uploaded files in the database instead.
Now, consider the following table:
db.define_table('dog',
Field('name')
Field('image', 'upload'))
where dog.image
is of type upload. To make the uploaded image go in the same record as
the name of the dog, you must modify the table definition by adding a
blob field and link it to the upload field:
db.define_table('dog',
Field('name')
Field('image', 'upload', uploadfield='image_data'),
Field('image_data', 'blob'))
Here "image_data" is just an arbitrary name for the new blob field.
Line 3 instructs web2py to safely rename uploaded images as usual, store the new name in the image field, and store the data in the uploadfield called "image_data" instead of storing the data on the filesystem. All of this is be done automatically by SQLFORMs and no other code needs to be changed.
With this tweak, the "uploads" folder is no longer needed."
"SQLFORM.factory
There are cases when you want to generate forms as if you had a database table but you do not want the database table. You simply want to take advantage of the SQLFORM
capability to generate a nice looking CSS-friendly form and perhaps perform file upload and renaming.
This can be done via a form_factory
. Here is an example where you generate the form, perform validation, upload a file and store everything in the session
:"
def create_excel(row):
from openpyxl import load_workbook
from openpyxl.writer.excel import save_virtual_workbook
from cStringIO import StringIO
wb = load_workbook(filename='/home/../Documents/web2py/applications/../static/excel.xlsx')
sheet_ranges = wb['Sheet1']
sheet_ranges['C4'] = row.last_name
sheet_ranges['C6'] = row.first_name
sheet_ranges['C8'] = row.age
sheet_ranges['C10'] = row.location
excel_file = StringIO()
excel_file.write(save_virtual_workbook(wb))
excel_file.seek(0)
return db.excelform.excel_file.store(excel_file, 'spreadsheet.xlsx')
db.define_table('excelform',
Field('last_name', 'string', requires=IS_NOT_EMPTY()),
Field('first_name', 'string', requires=IS_NOT_EMPTY()),
Field('age', 'string', requires=IS_NOT_EMPTY()),
Field('location', 'string', requires=IS_NOT_EMPTY()),
Field('excel_file', 'upload', compute=create_excel),
Field('created_by', 'reference auth_user',
default=auth.user_id, readable=False, writable=False))
@auth.requires_login()
def excelform():
record = db.excelform(request.args(0))
form = SQLFORM(db.excelform, record,
message_onsuccess='Thanks! The form has been submitted.',
message_onfailure='Please correct the error(s).').process()
return dict(form=form)
grid = SQLFORM.grid(db.excelform.created_by == auth.user_id)
There is no need to store the data in the session and then redirect to another action to create the file. Instead, just do it all at once. Also, if you want to store the file (safely) and make it easily retrievable, then add an upload field to the database table and store it that way. Finally, if you want to associated files with their creators, just add a reference field to the excelform table to reference the auth_user record of the currently logged in user. This can all be simplified as follows:
In a model file:
def create_excel(row):
from openpyxl import load_workbook
from openpyxl.writer.excel import save_virtual_workbook
from cStringIO import StringIO
wb = load_workbook(filename='/home/../Documents/web2py/applications/../static/excel.xlsx')
sheet_ranges = wb['Sheet1']
sheet_ranges['C4'] = row.last_name
sheet_ranges['C6'] = row.first_name
sheet_ranges['C8'] = row.age
sheet_ranges['C10'] = row.location
excel_file = StringIO()
excel_file.write(save_virtual_workbook(wb))
excel_file.seek(0)
return db.excelform.excel_file.store(excel_file, 'spreadsheet.xlsx')
db.define_table('excelform',
Field('last_name', 'string', requires=IS_NOT_EMPTY()),
Field('first_name', 'string', requires=IS_NOT_EMPTY()),
Field('age', 'string', requires=IS_NOT_EMPTY()),
Field('location', 'string', requires=IS_NOT_EMPTY()),
Field('excel_file', 'upload', compute=create_excel),
Field('created_by', 'reference auth_user',
default=auth.user_id, readable=False, writable=False))
The above adds the excel_file upload field to your model and defines it as a computed field. When an insert is made, the create_excel function is called. It creates the workbook, but instead of using wb.save() to create the file directly, it uses save_virtual_workbook to convert the workbook to a string. It then writes the string to a StringIO object, which is ultimately passed to the .store() method of the upload field. The .store() method creates the file and returns the filename that web2py created for it, which is ultimately stored in the upload field itself. The second argument to .store() is the filename you will see when you download the file (but no the filename used to actually store the file on the filesystem).
The created_by field is a reference to auth_user, with the default set to the ID of the current user (it is not readable or writable, so will not appear in the form).
Then, in the controller:
@auth.requires_login()
def excelform():
record = db.excelform(request.args(0))
form = SQLFORM(db.excelform, record,
message_onsuccess='Thanks! The form has been submitted.',
message_onfailure='Please correct the error(s).').process()
return dict(form=form)
The controller is now quite simple -- it just creates and processes the form -- the rest of the logic is handled in the model. Note, assuming being a registered user is required, you should use the @auth.requires_login() decorator here.
If you want to show only the files of the current user, you can do:
grid = SQLFORM.grid(db.excelform.created_by == auth.user_id)
Anthony
--
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 a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/B4H1Q6jV9S4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
To unsubscribe from this group and all its topics, send an email to web2py+unsubscribe@googlegroups.com.
I am not sure if this is because nothing appears to save in the first place, or if it is because I am using the function wrong.
To unsubscribe from this group and all its topics, send an email to web2py+unsubscribe@googlegroups.com.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
--
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 a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/B4H1Q6jV9S4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
To unsubscribe from this group and all its topics, send an email to web2py+unsubscribe@googlegroups.com.
--
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 a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/B4H1Q6jV9S4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+unsubscribe@googlegroups.com.
sheet_ranges['C10'] = row.location
sheet_ranges['C10'] = row.located