我在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.php
或index.html
文件,则会自动提供该文件。
我的要求: -
localhost:3333/results/1
请求,我应该index.html
我可以通过添加路由并检查index.html是否存在子目录然后提供它来对Flask执行相同的操作。我发现了一些类似的指针here
我目前使用两条路线来获取功能。肯定有更好的方法。
为什么我要包含有关静态目录的详细信息?
我极有可能做错了什么。请告诉我。谢谢:))
答案 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解释器,我们可以通过另一台服务器为它们提供服务,几乎不需要额外的工作。