загрузка web2py с исходным именем файла

Я хочу загрузить файл с SQL.фабрика() Я просто хотел бы сохранить исходное имя файла мой код в настоящее время

form = SQLFORM.factory(
    Field('file_name', requires=IS_NOT_EMPTY()),
    Field('file', 'upload',uploadfolder=upload_folder))
if form.accepts(request.vars, session):  #.process().accepted:
    response.flash = u'File uploaded'
    session.your_name = form.vars.file_name
    session.filename = request.vars.file 
elif form.errors:
    response.flash = 'form has errors'
return dict(form=form)

Я думаю, сессия.именем = запрос.Вар.файл-это имя файла. Почему у меня автоматически no_data имя файла.что-то.23u8o8274823zu4i2.smth

спасибо

3 ответов


во-первых,request.vars.file является Python


если вы просто переименуете файл, это нарушит механизм загрузки. Кроме того, иногда вы можете сохранить файл под другим именем, чем оригинал. Предположим, у вас есть следующая модель:

db.define_table("files",
Field("name", unique=True),
Field("file", "upload"))

вам нужно расширить поле загрузки с помощью настраиваемых функций хранения и извлечения:

Field("file", "upload", custom_store=store_file, custom_retrieve=retrieve_file)

функции просто пишут / читают файл из фиксированного каталога загрузки:

import os
import shutil

def store_file(file, filename=None, path=None):
    path = "applications/app_name/uploads"
    if not os.path.exists(path):
         os.makedirs(path)
    pathfilename = os.path.join(path, filename)
    dest_file = open(pathfilename, 'wb')
    try:
            shutil.copyfileobj(file, dest_file)
    finally:
            dest_file.close()
    return filename

def retrieve_file(filename, path=None):
    path = "applications/app_name/uploads"
    return (filename, open(os.path.join(path, filename), 'rb'))

теперь в контроллере нужно изменять форму.vars перед вставкой/обновлением базы данных и установкой имени файла. Если вы хотите сохранить оригинальное имя загруженного файла, в этом нет необходимости.

def validate(form):
    # set the uploaded file name equal to a name given in the form
    if form.vars.file is not None:
        form.vars.file.filename = form.vars.name

вам также нужно определить функцию для загрузки файла в качестве сборки в ответ.скачать не будет работать:

import contenttype as c

def download():
    if not request.args:
        raise HTTP(404)
    name = request.args[-1]
    field = db["files"]["file"]
    try:
        (filename, file) = field.retrieve(name)
    except IOError:
        raise HTTP(404)
    response.headers["Content-Type"] = c.contenttype(name)
    response.headers["Content-Disposition"] = "attachment; filename=%s" % name
    stream = response.stream(file, chunk_size=64*1024, request=request)
    raise HTTP(200, stream, **response.headers)

чтобы соединить точки, вам нужно построить форму. В приведенном ниже примере я использую новый механизм сетки, который намного лучше, чем старые школьные формы (но еще не документированные в книге.)

upload = lambda filename: URL("download", args=[filename])

def index():
    grid = SQLFORM.grid(db.files, onvalidation=validate, upload=upload)
    return {"grid":grid}

если вы не хотите всю причудливость сетки, эквивалентный код контроллера:

def index():
    if len(request.args):
        form=SQLFORM(db.files, request.args[0], upload=URL("download"))
    else:
        form=SQLFORM(db.files, upload=URL("download"))

    if form.process(onvalidation=validate).accepted:
        response.flash = "files updated"

    return {"form":form}

Так что я сделал это :) вот мой код

import os
upload_folder ='C:\Python27\web2py'
sl = "\"
path = upload_folder + sl

def display_form():

     form = SQLFORM.factory(
        Field('file_name', requires=IS_NOT_EMPTY()),
        Field('file', 'upload',uploadfolder=upload_folder))


     if form.accepts(request.vars, session):  #.process().accepted:
        session.file_name= form.vars.file_name
        coded_name = form.vars.file 
        orig_name = request.vars.file.filename
        os.rename(path + coded_name, path + orig_name)
        response.flash = u'datoteka naložena'

    elif form.errors:
        response.flash = 'form has errors'
    return dict(form=form)

Я знаю, что это, вероятно, не лучшее решение, но поскольку оно работает, мне нравится :)

спасибо Энтони