V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
rogwan
V2EX  ›  Python

分页显示,下一页要记住表单值,一般用 url 传值?还是 js 传?

  •  
  •   rogwan · 2016-07-25 13:43:53 +08:00 · 5370 次点击
    这是一个创建于 2839 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个搜索页的表单,查找出来的内容比较多,要分页显示。用 SQLAlchemy 的 paginate()做分页,默认页是 OK 的,下一页就记不住 SearchForm 里的 value = form.keyword.data 值(搜索的关键字)。

    一般是把这个 value 值,通过 app.route 里的 url 形式的参数传值? 还是用 js 的方式传比较好?

    23 条回复    2016-07-26 12:41:37 +08:00
    jugelizi
        1
    jugelizi  
       2016-07-25 13:55:26 +08:00
    你看百度搜索
    hiro0729
        2
    hiro0729  
       2016-07-25 15:25:09 +08:00
    当然是 url 传值了,按 F5 刷新能保留状态,要是纯 js 传,页面刷新参数全初始化了。
    WittBulter
        3
    WittBulter  
       2016-07-25 15:28:17 +08:00
    url 传值比较好
    但是一般在 js 里面取,建一个规范的对象树
    如果没有就把 url 参数转到对象上存起来,这样每次取速度都很高
    learnshare
        4
    learnshare  
       2016-07-25 15:28:56 +08:00
    URL 太长的话,存 localStorage
    aleen42
        5
    aleen42  
       2016-07-25 15:45:44 +08:00
    localStorage 时间有点长,个人觉得可以使用 cookie 存储一下用户的行为就可以了。
    kaneg
        6
    kaneg  
       2016-07-25 16:24:38 +08:00
    看你考虑不考虑页面刷新的问题,不考虑的话,参数都放在页面里,请求用 ajax ,不要太简单。
    如果要考虑刷新,那就不得不用上面几位提到的方法了
    orzfly
        7
    orzfly  
       2016-07-25 16:56:51 +08:00
    @aleen42 Cookie 是会发到服务器去的…
    rogwan
        8
    rogwan  
    OP
       2016-07-25 17:45:26 +08:00
    @hiro0729
    @WittBulter

    参考官方文档介绍,用 url 方式传值:
    http://flask.pocoo.org/docs/0.11/quickstart/#url-building
    --------------------
    你可以用 args 属性来接收在 URL ( ?key=value ) 中提交的参数:
    searchword = request.args.get('key', '')
    --------------------
    @app.route('/search', methods=['GET'])
    def search():
    form = SearchForm():
    keyword = form.search_keyword.data

    value = request.args.get('keyword')

    这样写,点击“下一页”,还是取不到 value 的值啊
    aleen42
        9
    aleen42  
       2016-07-25 17:45:48 +08:00
    @orzfly 服务器需要页码去分页查询吗?还是数据全 load 到 view 层了?
    domty
        10
    domty  
       2016-07-25 17:55:03 +08:00
    url 正好,
    如果 url 过长,可以考虑本地弄几个 hidden 的 input 去存,跳转分页的时候再用 js 去拼 url 。
    rogwan
        11
    rogwan  
    OP
       2016-07-25 17:55:53 +08:00
    @kaneg

    ajax 异步加载的方法,我只用过和后台请求简单的数据返回。
    页面刷不刷新都可以,主要是这个 ajax 配合 Flask SQLAlchemy 的 Pagination 分页,以前没使过>_<!!,不知道要调试多久才能搞定。。。 有推荐的文章可以参考下吗?
    chaegumi
        12
    chaegumi  
       2016-07-25 18:23:39 +08:00
    chaegumi
        13
    chaegumi  
       2016-07-25 18:24:16 +08:00
    chaegumi
        14
    chaegumi  
       2016-07-25 18:25:29 +08:00
    honmaple
        15
    honmaple  
       2016-07-26 01:15:21 +08:00
    第一页使用 wtforms,之后的将 keyword 传入模板,
    构造下一页时 url_for 加上 search=keyword 参数,
    后台就能直接 value = request.args.get('search') 得到
    rogwan
        16
    rogwan  
    OP
       2016-07-26 06:43:55 +08:00
    @honmaple 嗯,是用 wtforms 的。现在遇到的问题是:在第一页通过 form 取到 keyword 之后,传给模板,分页的下一页是通过 SALAlchemy 的 paginate()方法,我在那里添加 url_for 参数,返回值是空的。搞得下一页,就成了空白。。。

    #form.py
    class SearchForm(Form):
    search_keyword = StringField('', validators = [DataRequired()])
    submit = SubmitField('Start Search')

    #view.py
    @app.route('/search', methods=['POST', 'GET'])
    def search():
    form = SearchForm():
    keyword = form.search_keyword.data

    page = request.args.get('page', 1, type=int)
    value = request.args.get('keyword')

    if form.validate_on_submit():
    pagination = Post.query.filter(Post.content.like(keyword))paginate(
    page, per_page=current_app.config['default'], error_out=False)

    posts = pagination.items
    return render_template('search.html', posts=posts, pagination=pagination, form=form, value=value)

    #search.html

    <div class="list">
    {% include 'list.html' %}
    </div>
    {% if pagination %}
    <div class="pagination">
    {{ macros.pagination_widget(pagination, '.search', value=value)}}
    </div>
    {% endif %}
    honmaple
        17
    honmaple  
       2016-07-26 10:03:47 +08:00
    如果是我做的话大概是这样

    def search():
    form = DoSearchForm()
    if form.validate_on_submit():
    search = form.search.data
    return redirect(url_for('search_content', search=search))
    return render_template('搜索页')


    def search_content():
    page = request.args.get('page')
    search = request.args.get('search')
    if not search:
    return redirect(url_for('search'))
    else:
    posts = Post.query.filter(Post.content.like(search)).paginate(
    page,
    per_page=current_app.config['default'],
    error_out=False)
    return render_template('显示内容页', posts=posts)
    rogwan
        18
    rogwan  
    OP
       2016-07-26 10:11:15 +08:00
    现在搞定了上面分页传值这个问题了,又出现新故障:
    https://example.com/search?keyword=foo&page=2
    在这个第二页的搜索表单里回传了 foo 参数,但是用户再手动输入别的 keyword (比如 xxoo ),点击“提交”后,还是显示原来的搜索结果(即:还是搜索 keyword=foo ,而不是搜索 keyword=xxoo )。
    rogwan
        19
    rogwan  
    OP
       2016-07-26 10:13:57 +08:00
    @honmaple 非常感谢!看起我上面的第二个问题,是需要你说的用 url_for 跳一次才能解决。只在一个函数里处理,判断写了好几层,自己都快看晕了。。。
    honmaple
        20
    honmaple  
       2016-07-26 10:22:25 +08:00
    使用一个函数的

    def search():
    form = DoSearchForm()
    page = request.args.get('page', type=int)
    search = request.args.get('search')
    if form.validate_on_submit() and request.method == 'POST':
    search = form.search.data
    return redirect(url_for('forums.search', search=search, page=1))
    else:
    topics = Topic.query.filter(Topic.content.like(search)).paginate(
    page,
    per_page=current_app.config['PER_PAGE'],
    error_out=False)
    return render_template('forums/search.html', topics=topics,form = form)
    honmaple
        21
    honmaple  
       2016-07-26 10:24:51 +08:00   ❤️ 1
    注意 POST 之后要使用重定向,否则总是会提醒你是否提交
    djx339
        22
    djx339  
       2016-07-26 11:08:44 +08:00
    可不可以把 query 的内容在后台存下来,每次带着指定的 query id 加上第几页,应该可以解决,估计就是改动有点大。
    rogwan
        23
    rogwan  
    OP
       2016-07-26 12:41:37 +08:00
    @honmaple 根据你提供的方案调试的基本都 OK 啦,谢谢你的建议!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2126 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:04 · PVG 19:04 · LAX 04:04 · JFK 07:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.