简体   繁体   English

Flask-表单提交后如何保持列表索引?

[英]Flask - how to keep list index after form submit?

I have a list of images that I want to display on a page. 我有一个要显示在页面上的图像列表。 These image names are formatted basically YYYYMMDD_HHMMSS.jpg . 这些图像名称的格式基本上为YYYYMMDD_HHMMSS.jpg I want this single page to either list all images, or only list and show those taken on a certain date (meaning a main page, not like /index to show all images, /date-specific to show some images). 我希望此页面可以列出所有图像,或仅列出并显示在特定日期拍摄的图像(这是一个主页,不像/index来显示所有图像, /date-specific来显示一些图像)。

So far, I have been able to show all images, and click "next"/"previous" buttons to loop through all images. 到目前为止,我已经能够显示所有图像,然后单击“下一个” /“上一个”按钮来循环浏览所有图像。 I also have a table below the image, showing all the images that are in the index. 我在图像下方还有一个表格,显示索引中的所有图像。

Works great - no issues. 效果很好-没问题。

However, I am also trying to implement a date filter, where the user can select a date from the Calendar Picker, and have the site filter out and only show photos on that day. 但是,我也试图实现一个日期过滤器,用户可以从日历选择器中选择一个日期,并过滤掉网站,只显示当天的照片。 So far, I can successfully filter one time. 到目前为止,我可以成功过滤一次 However, when I click "next"/"previous" buttons, or choose an image from the table, it resets back to the full list of images. 但是,当我单击“下一个” /“上一个”按钮或从表中选择一个图像时,它将重置回完整的图像列表。

How do I keep the filtered list? 如何保留过滤列表? I thought I could do it by keeping the date chosen in the Input field, but after using the "next"/"previous" buttons, the whole page resets and it clears that field. 我以为可以通过在“输入”字段中保留选择的日期来做到这一点,但是在使用“下一个” /“上一个”按钮之后,整个页面将重置并清除该字段。

I also tried including the list in the HTML portion, but it still returns all the photos. 我还尝试将列表包括在HTML部分中,但它仍返回所有照片。 (Also makes the URL ugly, since it includes the image list for each photo listed in the table): (由于URL中包含表中列出的每张照片的图像列表,因此URL也很难看):

<td><a href="{{ url_for('default_template', chosen_image=image, image_list=image_list) }}"> {{ image }} </a></td>

Here's a .gif of the page I'm working on. 这是我正在处理的页面的.gif。 . First, you'll see I can successfully click around, navigate between all photos. 首先,您会看到我可以成功单击并在所有照片之间导航。 Then, I can successfully filter to show photos on a specific date. 然后,我可以成功过滤以显示特定日期的照片。 However, anything past that keeps sending me back to the full image list. 但是,任何过去的事情都会使我回到完整的图像列表。

Anyways, without further ado, here's the codes. 不管怎么说,下面是代码。 (Note I try to keep it minimal, so might have omitted an important piece, so please let me know if I need to post something else here): (请注意,我尝试将其保持在最低水平,因此可能省略了重要的内容,因此,如果需要在此处发布其他内容,请告诉我):

routes.py route.py

import os
import random
from flask import render_template, url_for, request, Blueprint, redirect  # noqa
from app import app

IMAGE_FOLDER = r"C:/MyPath/Test"
FAVORITE_LIST = os.path.join(IMAGE_FOLDER, "favorites.txt")

blueprint = Blueprint('images', __name__,
                      static_url_path='/static/images',
                      static_folder=IMAGE_FOLDER)
app.register_blueprint(blueprint)

images = os.listdir(IMAGE_FOLDER)


image_urls = ["20190411_123200.jpg", ... other images in a list]

class Photo_Index():
    def __init__(self, index=0):
        self.index = index

    def increase_number(self, num_images):
        if self.index == num_images:
            self.index = 0
        else:
            self.index = self.index + 1
        return self.index

    def decrease_number(self, num_images):
        if self.index == 0:
            self.index = num_images
        else:
            self.index = self.index - 1
        return self.index

    def random_number(self, num_images):
        self.index = random.randint(0, num_images)
        return self.index

    def set_number(self, number):
        self.index = number
        return self.index


# functions to create and edit Favorites. this works so I'm excluding]


def day_month_year(filename):
    """
    Takes a string `20190212` and pulls out Year, Month, Date
    """
    year = filename[:4]
    month = filename[4:6]
    day = filename[6:8]
    return str(year + "-" + month + "-" + day)


def get_files_on(specific_date):
    _files = []
    print("\nLooking for files on:", specific_date, "\n")
    for file in image_urls:
        # print(file, day_month_year(file))
        if day_month_year(file) == specific_date:
            _files.append(file)
    return _files


photo_index_obj = Photo_Index()
fav_photo_index = Photo_Index()


def update_index(rqst, indx_obj, num_images):
    print("Updating index, have", num_images, "photos")
    if num_images == 1:
        indx_obj.set_number(0)
    elif 'prev-photo' in rqst.form:
        indx_obj.decrease_number(num_images)
    elif 'next-photo' in rqst.form:
        indx_obj.increase_number(num_images)
    elif 'random-photo' in rqst.form:
        indx_obj.random_number(num_images)
    return indx_obj

@app.route("/<chosen_image>", methods=["GET", "POST"])
@app.route("/", methods=["GET", "POST"])
def default_template(date=None, image_list=None, chosen_image=None):
    if image_list is None:
        image_list = image_urls
    num_images = len(image_list) - 1
    if request.method == "POST":
        if 'go-to-date' in request.form:
            date = request.form['go-to-date']
            image_list = get_files_on(date)
            num_images = len(image_list) - 1
            photo_index_obj.set_number(0)
            if len(image_list) == 0:
                image_list = ["no_images_for_date.jpg"]
        elif 'prev-next-buttons' in request.form:
            print("Updating index, have", num_images, "photos")
            update_index(request, photo_index_obj, num_images)
        elif 'favorite-photo' in request.form:
            add_to_favorites(image_list[photo_index_obj.index])
        elif 'un-favorite-photo' in request.form:
            remove_from_favorites(image_list[photo_index_obj.index])
    if chosen_image is None:
        chosen_image = image_list[photo_index_obj.index]
    elif chosen_image is not None:
        photo_index_obj.set_number(image_list.index(chosen_image))
    favorite = is_favorite(image_list[photo_index_obj.index])
    print("Images:", image_list)
    return render_template('index.html',
                           title="Local Image Viewer",
                           photo_index=photo_index_obj.index,
                           image=chosen_image,
                           image_list=image_list,
                           favorite=favorite)

@app.route("/<chosen_image>", methods=["GET", "POST"])
def chosen_image(chosen_image):
    date = request.form['go-to-date']
    return default_template(date=date,
                            chosen_image=chosen_image)

index.html (I omitted the Select list, as that's kind of superfluous for this post) index.html(我省略了“选择”列表,因为这对于本帖子来说是多余的)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{{ title }}</title>
    <link rel="stylesheet" type="text/css" href= "{{ url_for('static',filename='styles/index.css') }}">
    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
</head>
<body>
{% extends "layout.html" %}
{% block content %}
    <h3>Index: {{ photo_index }}</h3>
    <h3>Filename: {{ image }}</h3>
    <div id="calendar-selector">
    {% include "/HTML Snippets/calendar.html" %}
    </div>
    <div class='image-container' id='image'>
        {% include "/HTML Snippets/favorite_button.html" %}
        <img src="{{ url_for('images.static', filename=image) }} " id="the-photo">
    </div>
    <div class='button-container' id='buttons'>
        <form action="" method="post">
            <input type="hidden" name="prev-next-buttons">
            <input type="submit" value="Prev photo" name='prev-photo'>
            <input type="submit" value="Next photo" name='next-photo'>
            <input type="submit" value="Random photo" name='random-photo'>
            <br/>
            <button type='button' id='rotate-button' onclick="rotateMeCounterClockwise('#the-photo')">Rotate Photo CounterClockwise</button>
            <button type='button' id='rotate-button' onclick="rotateMeClockwise('#the-photo')">Rotate Photo Clockwise</button>
        </form>
    </div>
    <div class='table-container'>
        <table id='image-list' name='select-from-table'>
            {% for image_row in image_list | batch(3) %}
            <tr>
                {% for image in image_row %}
                <td><a href="{{ url_for('default_template', chosen_image=image) }}"> {{ image }} </a></td>
                {% endfor %}
            </tr>
            {% endfor %}
        </table>
    </div>
{% endblock %}
</body>
</html>

and the calendar bit, calendar.html 日历位calendar.html

{% block topscripts %}
    <link rel="stylesheet" type="text/css" href= "{{ url_for('static',filename='styles/calendar.css') }}">
    <script>
        $(function() {
            $("#datepicker").datepicker({dateFormat: 'yy-mm-dd'});
        });
    </script>    
{% endblock %}

{% block content %}
<form method="post" action="{{ url_for('default_template') }}">
    <input type="hidden" name="calendar-form">
    <p>
        Date: <input type="text" id="datepicker"  name='go-to-date'
        {% if request.form['go-to-date'] is not none %}
            value="{{request.form['go-to-date']}}"
        {% endif %}

        ></p>
    <input type="submit">
</form>
{% endblock %}

{% block endscripts %}

{% endblock %}

You need to pass along enough information in your next/previous form and in the table links to re-apply the date filter. 您需要在下一个/上一个表格中以及表格链接中传递足够的信息,以重新应用日期过滤器。 Your calendar form is separate from the next/previous navigation form, the browser won't serialise information from one when submitting the other. 您的日历表单与下一个/上一个导航表单是分开的,当提交另一个表单时,浏览器不会序列化其中一个的信息。 Clicks on <a href="..."> links will not include the date input field value either. 单击<a href="...">链接也将不包括日期输入字段值。

Note that clicks on the table links generate GET requests, so you need to look for go-to-date in the request.values mapping to accommodate both query parameters and form data. 请注意,单击表链接会生成GET请求,因此您需要在request.values映射中查找go-to-date ,以容纳查询参数和表单数据。

You need to look for this parameter not only when you receive a POST request, but for all requests: 您不仅需要在收到POST请求时查找此参数,还需要为所有请求查找此参数:

if 'go-to-date' in request.values:
    date = request.values['go-to-date']
    image_list = get_files_on(date)
    photo_index_obj.set_number(0)
    if len(image_list) == 0:
        image_list = ["no_images_for_date.jpg"]
else:
    image_list = image_list or image_urls
num_images = len(image_list) - 1

if request.method == 'POST':
    # ...

Then generate URLs that include the parameter: 然后生成包含参数的URL:

{%- set url_params = {'go-to-date': request.values['go-to-date']} if request.values['go-to-date'] else {} -%}
{% for image in image_row %}
<td><a href="{{ url_for('default_template', chosen_image=image, **url_params) }}"> {{ image }} </a></td>
{% endfor %}

For the next/previous form, just add a hidden input field with the current go-to-date value: 对于next/previous表单,只需添加一个具有当前go-to-date值的隐藏输入字段:

<form action="" method="post">
    <input type="hidden" name="prev-next-buttons">
    {%- if request.values['go-to-date'] -%}
    <input type="hidden" name="go-to-date" value="{{ request.values['go-to-date'] }}">
    {%- endif -%}

    <input type="submit" value="Prev photo" name='prev-photo'>
    <input type="submit" value="Next photo" name='next-photo'>
    <input type="submit" value="Random photo" name='random-photo'>
    <br/>
    <button type='button' id='rotate-button' onclick="rotateMeCounterClockwise('#the-photo')">Rotate Photo CounterClockwise</button>
    <button type='button' id='rotate-button' onclick="rotateMeClockwise('#the-photo')">Rotate Photo Clockwise</button>
</form>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM