让Flask在目录

时间:2016-09-17 08:53:42

标签: python flask

我在Flask中有2个静态目录。

静态/

  • css/
  • js/

结果/

  • 1/
    • index.html
    • details.json
  • 2/
    • index.html
    • details.json

我跟着其他一些答案,浏览了the documentation for serving static files

app = Flask(__name__)
app.config['RESULT_STATIC_PATH'] = "results/"

@app.route('/results/<path:file>')
def serve_results(file):
    # Haven't used the secure way to send files yet
    return send_from_directory(app.config['RESULT_STATIC_PATH'], file)

使用以下代码,我现在可以请求results目录中的文件。

我更熟悉PHP和Apache。如果某个目录包含index.phpindex.html文件,则会自动提供该文件。

我的要求: -

  • 访问结果目录中的任何文件
  • 如果我发送localhost:3333/results/1请求,我应该index.html

我可以通过添加路由并检查index.html是否存在子目录然后提供它来对Flask执行相同的操作。我发现了一些类似的指针here

我目前使用两条路线来获取功能。肯定有更好的方法。

为什么我要包含有关静态目录的详细信息?
 我极有可能做错了什么。请告诉我。谢谢:))

3 个答案:

答案 0 :(得分:2)

试试这个:

@app.route('/results/<path:file>', defaults={'file': 'index.html'})
def serve_results(file):
    # Haven't used the secure way to send files yet
    return send_from_directory(app.config['RESULT_STATIC_PATH'], file)

这是传递该参数的默认值的方法。但是,我不同意这一点,如果您想提供静态内容,只需在您的网络服务器中设置规则(在您的情况下为apache)。

答案 1 :(得分:1)

我正在使用以下单一路由解决方案,“默认值”对我不起作用,因为它停止提供任何其他文件。

当路径没有以斜杠结束时,您也可以使用斜杠生成到路径的重定向,而不是引发错误。没有这个斜杠,但服务索引文件导致相对路径出现问题。

public async Task<List<Order> GetOrdersFromTradeGeckoCount()
{
        string orderLimit = base.StorePlugin.Store.OrderLimit.HasValue ? base.StorePlugin.Store.OrderLimit.Value.ToString() : "250";
        string filters = string.Format("?status=finalized&limit={0}", orderLimit);
        HttpResponseMessage response = _requestHelper.GetHttpResponse("orders" + filters);
        var tgOrders = GetOrdersResponse(response);
        //Async Convert and Save Order
        await ConvertToORouterOrdersAsync(tgOrders).ConfigureAwait(false);
        return ConvertToORouterOrdersCount(tgOrders);
}

public Task ConvertToORouterOrdersAsync(List<TGOrder> tgOrders)
{
    return Task.Run(() =>
    {
        var orderMgr = new OrderDAC();
        var orders = new List<Order>(tgOrders.Count());
        foreach (TGOrder tgOrder in tgOrders)
        {
            try
            {
                var order = new Order();
                var orderId = TryConvertInt64(CleanUpOrderId(tgOrder.order_number));

                if (orderId == null) continue;

                var tempOrderId = string.Format("{0}{1}", base.StoreId, orderId.Value);
                order.OrderId = TryConvertInt64(tempOrderId).Value;
                order.StoreOrderId = tgOrder.id.ToString();
                order.WarehouseOrderId = tgOrder.order_number;

                var orderFromDb = await orderMgr.GetOrder(order.OrderId, base.StoreId);
                if (orderFromDb != null) continue; // make sure we only import new order(i.e. doesn't exists in database)

                // shipping address
                var tgShippingAddress = GetAddress(tgOrder.shipping_address_id);
                if (tgShippingAddress == null) continue;

                order.ShipFirstName = tgShippingAddress.first_name;
                order.ShipLastName = tgShippingAddress.last_name;
                order.ShipCompanyName = tgShippingAddress.company_name;
                order.ShipAddress1 = tgShippingAddress.address1;
                order.ShipAddress2 = tgShippingAddress.address2;
                order.ShipCity = tgShippingAddress.suburb;
                order.ShipState = tgShippingAddress.state;
                order.ShipPostalCode = tgShippingAddress.zip_code;
                order.ShipCountry = tgShippingAddress.country;
                order.ShipPhoneNumber = tgShippingAddress.phone_number;

                order.CustomerEmail = tgOrder.email;

                // billing address
                var tgBillingAddress = GetAddress(tgOrder.billing_address_id);
                if (tgBillingAddress == null) continue;

                // line items
                var lineItems = GetOrderLineItems(tgOrder.id);
                foreach (TGOrderLineItem lineItem in lineItems)
                {
                    var ol = new OrderLine();
                    if (lineItem.variant_id.HasValue)
                    {
                        var variant = GetVariant(lineItem.variant_id.Value);
                        if (variant == null) continue;
                        ol.ProductName = variant.product_name;
                        ol.SKU = variant.sku;
                        ol.ThreePLSKU = ol.SKU;
                        ol.Qty = Convert.ToInt16(TryGetDecimal(lineItem.quantity));
                        ol.OrderId = order.OrderId;
                        ol.Price = TryGetDecimal(lineItem.price);
                        ol.SubTotal = (ol.Qty * ol.Price);
                        ol.StoreOrderLineId = Convert.ToString(lineItem.id);
                        order.OrderLines.Add(ol);
                    }
                }
                var validator = new Validator(base.Task);
                if (validator.IsValidOrder(order))
                {
                    orderMgr.Add(order);
                }
            }
            catch (Exception ex)
            {
                AppendError(ex.Message);
            }
        }
    });
}

答案 2 :(得分:0)

我找不到只使用一条路线的解决方案。我最终使用了它。

@app.route('/results/<path:filename>')
def serve_static(filename):
    return send_from_directory("results/", filename)

@app.route('/results/<guid>')
def index(guid):
  return send_from_directory("results/" + guid, 'index.html')

其他建议

@ipinak建议使用defaults={'file': 'index.html'}作为另一个参数。 没有解决这个问题,因为它会导致一些安全问题,@ ipinak已经足够好去研究了。 defaults是一个很好的选项,我也会在我的应用程序的其他地方尝试使用它。

@dirn在评论中建议使用Apache / Nginx来提供静态文件。它可以节省时间,因为我不必在Flask中实现这些东西。由于静态文件不必传递给Python解释器,我们可以通过另一台服务器为它们提供服务,几乎不需要额外的工作。