作者归档:白宦成

关于白宦成

独立开发者, 自由职业者, 写作者

brown wooden house on top of mountain during daytime

聊聊丽江

今年的 6 月份, 我去了趟云南,此次去,我去了昆明、大理、丽江,泸沽湖,接下来我会依次把这几个地方都写一写。

关于丽江

我知道丽江,还是从酒吧、大冰、丽江手鼓《小宝贝》来的。酒吧和围绕着酒吧的丽江艳遇之都,丽江之名,在我的印象中不算特别好。而大冰,虽然我并不看,但堂弟的书架上常有大冰的书,也算是一个网红作者了。小宝贝则不用多说,在那段时间里,这首歌曲被疯狂翻唱,整体曲调好听轻快。

这是在没有去丽江之前,我心中的丽江印象。

丽江初印象

我是坐火车从大理到丽江的,遗憾的是忘了提前预约旅游专列 Y761 ,只是坐了普通的高铁到的,略显无聊。高铁上的体验远不如开车,而时间上也相差无几。下次,如果预约不上 Y761,我可能会选择直接从大理开车到丽江。

丽江站距离丽江古城有不远的距离,我从火车上下来,坐了半个小时的出租车,才到丽江古城边上。

d2b5ca33bd970f64a6301fa75ae2eb22 5
丽江古城北一角,我住的酒店就在这里

这里值得一提的是,丽江其实不止一座古城,我们一般意义上的「丽江古城」,其实是大研古城,而在丽江市北边,还有一个「束河古镇」,也是一座古城。

d2b5ca33bd970f64a6301fa75ae2eb22 6
丽江火车站到丽江古城的距离

古城周边,生活不便

第一次来,我选择了住在古城周边,主要考虑的还是方便浏览,且这次在丽江我没有租车,所以出行也没那么方便。

然鹅,这个决定是错误的,也是让我后续绝不住古城周边的原因。

我住的位置在大理古城附近的东岳巷,这里有不少的客栈、旅店,因为从巷子口走出去,对面就是丽江古城,所以从旅游的视角来看非常方便。但另一面是,玉缘路、金虹路并不是一个很宽敞的路,经常你出门的时候发现,这条路上堵了非常多的车,导致你在这里打车出行的体验极差。

另一方面,丽江古城里大量的商业店铺,导致这里其实晚上是略显吵闹的。我住在丽江古城外,噪音尚可。而那些丽江古城内的旅店,想想噪音怕是让你需要戴上耳塞睡觉的程度了。

d2b5ca33bd970f64a6301fa75ae2eb22 7

商业化严重的丽江古城

丽江古城给我的感觉便是,一个商业化及其严重的古城。大部分人来就是来体验一下「古城风情」,但你到了以后,可能大部分时候看到的要么是各种各样的商店, 要么是酒吧一条街的唱歌跳舞。

说好的风土人情,已经消失不见,取而代之的,是千篇一律的纳西族妆造和拍照的小姐姐。

不能免俗,我也去了丽江的小酒馆。从众多的酒吧中,找到了一个比较安静的,可以坐下来静静听民谣的酒吧。支付了人均 60 的位费,就开始听歌手唱歌。

d2b5ca33bd970f64a6301fa75ae2eb22 8
我们去的青鸟小酒馆

我去的时候,歌手已经唱了很久,于是唱了不多几首,便离开了,想着可能是去休息了,也可能是到下一个酒吧继续唱歌。

在小酒馆唱歌的歌手
thbsa8
招待完客人的老板娘,也上来唱了两首

除了酒吧,似乎没有什么值得我在夜晚在丽江古城继续逛逛的理由,于是便很早就离开古城,回去休息了。

第二天,我去了朋友介绍的唠叨坊,来尝尝特色的带皮黑山羊火锅。之前吃的比较多的是简阳羊汤火锅,这次试试云南的带皮羊肉火锅。

z8a8ln
d2b5ca33bd970f64a6301fa75ae2eb22 11

黑山羊火锅除了有点咸,别的倒是不错,独特的风味和造型,让我略微有点感受到风土人情的错觉。当然,实惠的价格令人满意,唠叨坊是自助式火锅,所以你可以大量的吃青菜(补一补旅行吃不到青菜的问题)。

4g0v7u

除了火锅,便是常规的在丽江古城找一处风景还不错的角落,拍拍照片,仅此而已。

丽江古城两天有点多,一天刚刚好

我这次给几个城市大体上都安排了 2 天的行程,在丽江的时候,是我感受到自己的时间有点多的场景。当然,也可能是因为我大部分时间是在古城里待着的原因。如果是自己开车的话,去趟束河古镇、拉市海,想来也是不错的。

如果你的行程中包含丽江,且只有一天,那么丽江古城刚刚好。如果你要安排更长的时间,可能就要考虑一下增加一些内容了。丽江古城虽好,但一天足矣。早上去拍拍照,中午吃个便宜坊,下午逛逛古城,撸撸猫,晚上到酒吧坐坐,古城至此便足够。

group of people under garment

你支持 LGBTIQA+ 么?

朋友问我:“你支持LGBTIQA+么?”

我的答案是,我不会反对。


对我来说,我始终能够感受到“有毒的男子气概”,也支持平权。但具体到某一个名词、一件事上,决策又不是那么的简单。

比如,LGBTIQA+ 对我来说,并没有什么特别的(就像美国某一个 KFC 换了一个接线员一样,对我来说可能毫无变化,当然,从蝴蝶效应的视角来看,依然有影响,但我有限的认知里,可能对我来说毫无影响),所以我既可以支持,也可以中立。

但如果落实到身边的朋友,我会选择支持。理由也很简单,既然对我来说,支持和中立一样,那我为什么不选择让朋友更开心的“支持”呢?

black Android smartphone

云南之旅支出分析

云南之旅的支出总体分析也做完了,接下来聊一下本次的支出。

支出明细参考 Airtable

总支出

本次旅行 6 月 17 号开始,6 月 25 日结束,共计 9 天。总支出 15309 元,日均开支 1701 元,日人均开支 850 元。

支出结构

对所有的支出条目进行梳理后,我发现不出意外的,在支出最大头的是出行相关。

d2b5ca33bd970f64a6301fa75ae2eb22 17

而在出行相关中,成本最高的是机票,其次是一嗨租车。一嗨租车因为实际上是我租了多天,所以单日成本可控。

d2b5ca33bd970f64a6301fa75ae2eb22 18

除了行之外,成本比较低的是住,可以看到,我在住上面花费了非常少的成本,主要的原因还是因为我去的时候云南还是属于淡季,所以整体的开销还好。

在游玩和景点方面,整体花费的不算特别多,成本大头的是伴手礼和旅拍的照片,其他的景点其实就还好。再加上我们俩基本上也没怎么去特别贵的景点,也就开销一般啦~

d2b5ca33bd970f64a6301fa75ae2eb22 28

吃的方面,这次来云南吃了不少当地的美食,所以开支比较大,符合预期(当然,比重还是有点收到惊吓),但总体还在可接受范围内。

d2b5ca33bd970f64a6301fa75ae2eb22 29

总结

旅游真的烧钱。。。不过穷家富路,出门了就别太在乎钱,不然还不如不出门。下次还去!

不过下次我可能会优化一下我的一些选择,比如租车可能会选择携程租电车 + 保险,来节约一些交通的开支。

rustlang

给 mdbook 增加备案号显示

由于 Gitbook 长期不维护,为了保障整个架构持续可用,所以导致我不得不从 Gitbook 迁移到 mdbook。

在使用 mdbook 的时候,有个问题是,我的不少电子书域名都是备案过后的,mdbook 又不像 gitbook 支持可以在目录里跳转外链,因此我需要自己实现给 mdbook 添加一个外链。

实现思路

由于没办法直接通过在 Markdown 当中实现跳转外链,那么一个比较简单粗暴的方法就是直接在模板当中添加,刚好 mdbook 在文档中有说明具体的操作方法

你只需要在 mdbook 的根目录中创建一个 theme 文件夹,并生成一个 index.hbs 文件,用于渲染页面。

接下来,你只需要在适当的位置添加上你需要的代码即可(下方的 toc 后面的 有序列表便是我手动添加的)

   <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                {{#toc}}{{/toc}}

                 <ol class="chapter">
                    <li class="chapter-item expanded "><a href="https://beian.miit.gov.cn/" target="_blank">这里是你的备案号</a></li>
                </ol>

            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>

        </nav>
Code language: HTML, XML (xml)

参考文档

https://github.com/rust-lang/mdBook/issues/1354

d2b5ca33bd970f64a6301fa75ae2eb22 23

淄博之旅

我去淄博其实是两个月之前了,由于拖延症,一直没写,于是我想,如果我再不写,可能我再也不会写了吧。OK,那就开始动手写吧!

缘由

我去淄博是在 5 月初,彼时我刚提车,于是便决定开车从天津前往淄博,一方面是练练车,另一方面刚好最近淄博火热,也去看看令人好奇的淄博烧烤。

人文景点

八大局

淄博作为一个以烧烤、烟火气火起来的城市,既然来,自然重点是看大家的生活,所以,到淄博的第一站,自然是少不了到八大局溜达溜达

d2b5ca33bd970f64a6301fa75ae2eb22 19

不过,当我去的时候,八大局已经在网络上火了很久,所以现场的人非常多。八大局也逐渐有了网红街的感觉了,比如紫米饼,已经被叫”网红紫米饼“了。

d2b5ca33bd970f64a6301fa75ae2eb22 20

考虑到排队正版的紫米饼时间太长,讨厌排队的我最终选择了一家非正版的紫米饼,试了试,味道还行。可能正版会更好吃,但排队实在太讨厌了…

d2b5ca33bd970f64a6301fa75ae2eb22 21

齐盛湖公园

从八大局出来,我们便开车去酒店休息,到了晚上,来到了淄博张店区的齐盛湖公园,据说这里有一个「海岱楼书店」,是曾经的最美书店,于是也跑来打卡,看看这个最美书店。

从外景来看,楼宇与湖光一起,远处还有山光,雀实不错。

pjp1az

走到近处,颜值也还算是能打

j0lopk

进入到里面后,内里的设计不像外部那么的古朴,反倒是还挺现代化的。但这个设计,挺讨喜的。

you7ru

作为一个最美书店,还是值得打卡的。

自然景观

潭溪山

由于安排了比较长的时间来淄博玩,所以我们除了逛一逛人文景观,还去了淄博的潭溪山景区,看看淄博的自然风光。

潭溪山的风光整体来说,还不错,与云南、西藏没办法比,但依然算得上清秀。

gfbh9l

潭溪山的话,我自己最喜欢的应该是这个透明栈道了。作为一个有恐高症的人,走这个透明栈道属实是胆战心惊,但,还是要走!

d2b5ca33bd970f64a6301fa75ae2eb22 27

旅行建议

淄博市是一个纵向偏长,横向较窄的城市布局,而我们在抖音上看到的八大局、烧烤一般都是在中间的张店区,而如果你只玩了张店区,你就错过了淄博的更多内容,淄博的临淄区、周村区、淄川区、博山区也有各自的特色和风格,如果你来了,我建议你除了在张店玩一玩,还要留有更多时间去看看更多不一样的淄博。

淄博市行政区划图

店铺推荐

在淄博的时候,我们吃了不少的烧烤,我最推荐的是淄川区的程大牛肉,这家店是牛肉烧烤专卖店。

一句话来描述的话,在我看来,程大牛肉是在用潮汕牛肉的思想做烧烤,这家和别家不一样,他是按部位卖牛肉烧烤的!你可以吃不同位置的牛肉做成的牛肉串!

推荐去试试看!不过,需要注意的是,他们家是预约制度的,所以你最好提前打电话联系一下,预约一个位置,以确保自己有位置。

总结

这次第一次来,我们只是简单玩了玩,对于淄博有一个更不一样的认识,而更加细致的内容,依然需要进一步的来淄博看看,体验一下淄博更细节的内涵,还要再去的!

APILetter

APILetter S1E5 如何设计一个符合 RESTFul 风格的批量操作的 OpenAPI 接口?

批量创建、批量更新、批量删除

批量获取说完了,接下来我们来聊聊批量更新,实际上批量更新、批量创建虽然有场景,但也不多,在这种场景下,我们已经很难像批量获取那样,在原有资源上进行操作,而是需要借助批量资源来实现批量操作。

以用户资源(User)为例,当我们需要对其进行批量创建、删除、更新时,我们需要创建一个批量资源 BulkUser,并通过对 BulkUser 操作,来创建用户。Bulk User 本质上是将请求的多个资源转换为了异步的任务,在发起后,开发者可以在任务结果中查询具体的值来使用。

如何理解异步的任务?
这里异步的任务更多是一种设计表现,并不强制要求一定异步。异步的表现设计和相关的接口实现,是为了给后续留出纵向扩展的空间。既 无论是否行为是否真实异步,都需要在返回结果中返回任务 ID & 任务状态,以便于开发者自行实现异步处理的逻辑。

{
    "code":0,
    "data":{
       "job":{          "id":"123",          "status":"ok"        },
        "results":[
            {
            ...
            }
        ]
    }
}
Code language: JavaScript (javascript)

批量创建

批量创建用户的操作和创建单个用户的操作是比较接近的,主要差异点在于 Path 上有区别,且传递参数时,会传递多个资源的属性。

批量创建用户

# request
POST /bulk_users/

{
    "users":[
        {
            // user1
            ...
        },
        {
            // user2
            ...
        }
    ]
}
# response
HTTP/1.1 200 OK
{
    "code":0,
    "data":[
       {
            // user1
            ...
        },
        {
            // user2
            ...
        }
    ]
}
Code language: PHP (php)

批量更新用户

批量更新时,你已经知道了你需要更新的资源的 ID,因此,可以这样设计的你的接口:

#request
PUT /bulk_users?id[]=1&id[]=2

{
    "gender":"other"
}

# response
HTTP/1.1 204 No Content
{
 "code":0,
    "data":[
       {
            // id=1
            ...
        },
        {
            // id=2
            ...
        }
    ]
}
Code language: PHP (php)

批量删除

有了上面的几个例子,批量删除就比较好定义了。就像这样:

#request
DELETE /bulk_users?id[]=1&id[]=2

# response
HTTP/1.1 200 OK
{
 "code":0,
    "data":[
       {
            // id=1
           "status":"deleted"
        },
        {
            // id=2
            "status":"deleted"
        }
    ]
}
Code language: PHP (php)

总结

批量操作在获取场景,可以考虑通过 List + Filter 的方式,或搜索的方式来实现一套更加标准的搜索接口,而规避提供定制化的自定义接口。从规范的视角,两者都是符合规范的,也可以都对用户提供,并不互斥。而对于没办法复用的创建、更新、删除,则可以考虑使用创建异步任务的方式,来实现批量操作,给开发者一个明确的异步预期,让开发者可以自行查询业务的实现方式。

d2b5ca33bd970f64a6301fa75ae2eb22

云南之旅流水账

云南之旅玩的非常的尽兴,6.17 ~ 6.25 ,全程共计 9 天,玩了昆明、大理、丽江、泸沽湖四个不同的地方,几乎每个地方待了 2 天左右,还是有非常多值得去和值得纪念的东西。不过,由于实在太多了,所以只能用流水账的方式来记录。在流水帐当中,着重说一些大面上的事情,而具体每个地方的更加详细的描述,则通过单独为每一个地方写一篇文章来说。

不过,为了方便你了解我的行程(抄作业),我在 Google Map 上准备了一份地图,方便你了解我去过的地方。如果你感兴趣的话,可以点击这个链接,看到我去的每一个地方,以及相应的评价。

行程总览(Overview)

日期地点描述
6.17天津,昆明,遵义天津飞昆明,遵义茅台机场中转; 落地后入住酒店,在昆明逛了南强街和南屏步行街
6.18昆明,大理早上去滇池,下午从昆明站出发前往大理,到大理后取车前往酒店入住后去大理古城.
6.19大理环洱海,期间去了喜洲古镇、大理圣托里尼
6.20大理,丽江逛崇圣寺三塔、坐感统索道上苍山,晚上还车并从大理坐车前往丽江,晚上住在丽江古城附近。
6.21丽江逛丽江古城、拍照、吃纳西族黑山羊火锅。
6.22丽江,泸沽湖吃过桥米线,从丽江出发去泸沽湖,晚上吃摩梭族烤鱼。
6.23泸沽湖,大理环泸沽湖,吃摩梭族烤鸡,下午开车回大理,并在大理古城拍照
6.24大理,昆明早上在大理吃过早餐,就开车出发去昆明,下午入住斗南花市旁的全季酒店,晚上逛斗南花市。
6.25昆明上午逛云南省博物馆,下午在翠湖公园溜达后,前往昆明长水国际机场。
9 天旅途的 Overview

感受

1. 云南的气候宜人

云南的气候是这次我体会最为深刻的。我在云南旅行的时候,恰逢天津正是高温的时刻,相比之下,云南的最高温不过 30 度简直是太过凉爽。

不过,虽然最高温不过 30 度,但在中午时刻,依然是比较热的,只是没有像北方是“烤”的感觉。而云南的湿度也不高,也不会有广东的“蒸”的感觉。

从气候上来讲,我觉得云南是比海南广东(太蒸),华北平原(太烤)要更好的。太宜居了。

d2b5ca33bd970f64a6301fa75ae2eb22 1
旅行期间天津的天气, 来源 2345
d2b5ca33bd970f64a6301fa75ae2eb22 2
旅行期间昆明的天气,来源 2345

不过,美中不足的是云南的紫外线强度也是太强了。云南 9 天,基本上每天都会喷安耐晒,整个旅程下来,我的小臂/脸上还是黑了一个色号。再去云南,我觉得我可能会直接选择穿防晒衣,物理防晒,最为靠谱。

2. 云南的风景美如画

云南的风光对我来说,可以比肩 19 年在西藏出差时的西藏风景。

蓝天、白云、青草地,还有洱海、泸沽湖这样的水,非常的舒服了。下面贴几张图,让大家感受一下(以下照片均出自原相机,无滤镜,但拍摄设备有 iPhone 13 和 Pixel 6):

d2b5ca33bd970f64a6301fa75ae2eb22 3
从昆明机场到塘子巷时地铁上拍的天和飞机
d2b5ca33bd970f64a6301fa75ae2eb22 4
昆明机场廊桥上拍的天空和机场
d2b5ca33bd970f64a6301fa75ae2eb22 5
滇池风景
d2b5ca33bd970f64a6301fa75ae2eb22 6
滇池水上风景
d2b5ca33bd970f64a6301fa75ae2eb22 7
洱海边拍的苍山
d2b5ca33bd970f64a6301fa75ae2eb22 8
洱海边
d2b5ca33bd970f64a6301fa75ae2eb22 9
泸沽湖夜景(晚上八点左右)
d2b5ca33bd970f64a6301fa75ae2eb22 10
泸沽湖草海
d2b5ca33bd970f64a6301fa75ae2eb22 11
泸沽湖俯瞰
d2b5ca33bd970f64a6301fa75ae2eb22 12
泸沽湖里格半岛

如此美景,我最大的感受就是,悔不该当初,我就应该带上相机来的!这次出行为了方便,我只带了拍立得和手机,所以拍不出我所看到的美景,再来我要带上我的6400、广角镜、长焦镜,把这些美景都拍下来!

3. 云南的美食很特别

这次去云南,赶上雨季推迟,所以没能吃当地的野生菌(我很想试试见手青,据说是云南的顶尖美味)。但也还是吃到了一些好吃的/ 特别的。

比如:在喜洲古镇吃到了炸蝎子🦂。

d2b5ca33bd970f64a6301fa75ae2eb22 13

比如,云南的粑粑,感觉就是各种不同的馅饼。

d2b5ca33bd970f64a6301fa75ae2eb22 14

也吃到了云南必吃的鲜花饼,现烤的是真的太好吃了。

d2b5ca33bd970f64a6301fa75ae2eb22 15

傣族风情手抓饭也少不了

d2b5ca33bd970f64a6301fa75ae2eb22 16

总结

云南这次的旅行给我的感受还是很深刻的,先简单总结三点。更细节的,后面一篇篇来。

可以肯定的是,云南,我还会再去的。

d2b5ca33bd970f64a6301fa75ae2eb22 34

被滥用的云南十八怪

这次去云南,看到了各种各样奇奇怪怪的“云南十八怪”,让我不得不来吐槽一把。

在没去云南之前,我就知道云南有个“云南十八怪”,在解释云南各种和中原地区差异比较大的生活习惯,但说实话,一直没怎么了解过具体的细节,因为不熟悉。

根据百度百科,云南十八怪是这样的:

你说奇怪不奇怪,云南就有十八怪。
四个竹鼠一麻袋,蚕豆花生数着卖;
袖珍小马多能耐,背着娃娃再恋爱;
四季衣服同穿戴,常年能出好瓜菜;
摘下草帽当锅盖,三个蚊子一盘菜;
石头长在云天外,这边下雨那边晒;
鸡蛋用草串着卖,火车没有汽车快;
小和尚可谈恋爱,有话不说歌舞代;
蚂蚱当作下酒菜,竹筒当作水烟袋;
鲜花四季开不败,脚趾常年露在外。

百度百科

但我在云南当地,见到了各种奇奇怪怪的十八怪,甚至炒酸奶也被编进了十八怪:“酸奶炒着卖”

d2b5ca33bd970f64a6301fa75ae2eb22 33
d2b5ca33bd970f64a6301fa75ae2eb22 34
d2b5ca33bd970f64a6301fa75ae2eb22 35

person holding sticky note

在 Render.com 上部署 Django 4.2

最近在写 Linux 中国的翻译工具的时候,后端我使用的是 Django,版本则选择了 Django 4.2,Python 3.11。在部署 Django 的时候,我选择使用 Render.com 来部署。 不过,在部署的时候,我遇到了一些问题,Render 官方提供的 Getting Started with Django on Render 会部署错误,所以有了今天这篇文章, 告诉大家如何把最新的 Django 4.2 部署到 Render 上。

初始化项目

Render 没有使用 pip,而是使用 Poetry 来管理 Django 项目的,因此,你需要使用 Poetry 来完成项目的初始化。

poetry init #初始化 Poetry 的 配置文件
poetry add django gunicorn # 添加依赖 Django 和 gunicorn
poetry run django-admin startproject linuxondjango .
Code language: PHP (php)

初始化项目基本上就是用 Poetry 替代 pip ,这里没有需要针对 Render 特化的部分,就不做过多的介绍。

编写逻辑代码

当你完成了项目的初始化之后,可以编写你自己的业务逻辑代码,这部分不再多讲,可以正常开发使用。

配置项目以支持 Render 的服务端环境。

1. 从环境变量中读取 Secret Key

Django 使用 Secret Key 作为 Session 加密等一些加密场景的 Salt 和 Seed,所以在 Django Admin 创建项目时,会默认生成一个 Session。不过出于安全考虑,最好不要将其放在代码中,而是在服务端生成后,通过环境变量来存储,避免代码泄露后导致的 session 被解密。

你需要在 settings.py 中,添加如下代码,来替代默认的 key。

import os
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('SECRET_KEY', default='your secret key')
Code language: PHP (php)

2. 在环境变量中读取 Debug 配置

Render 会自动配置一些环境变量,因此,你可以直接通过判断当前环境上下文来确认当前是否是在 Render 的服务端,如果不在,则配置 Debug 为 True,来解决线上不使用 Debug 模式的需求。

DEBUG = 'RENDER' not in os.environ
Code language: JavaScript (javascript)

3. 从环境变量中读取可用域名

Django 是有域名配置的,非配置域名,无法访问当前应用,因此,你需要在 Render 当中读取域名,来确保可以正常访问。当然,如果你自己配置了自己的域名,也可以直接手动写在 ALLOWED_HOSTS 当中。

ALLOWED_HOSTS = []

RENDER_EXTERNAL_HOSTNAME = os.environ.get("RENDER_EXTERNAL_HOSTNAME")
if RENDER_EXTERNAL_HOSTNAME:
    ALLOWED_HOSTS.append(RENDER_EXTERNAL_HOSTNAME)

Code language: JavaScript (javascript)

配置 render.yml 来支持 Render BluePrint

你可以直接复制下面的内容,来作为你的项目的启动配置。其中 build.sh 为构建项目的配置。

build.sh

build.sh 当中最重要的是重新安装 Poetry,因为我使用的是 Python 3.11.4, 和 Render 默认的 Python 3.7 不匹配,所以没办法直接用默认的 Poetry,需要自动手动升级 Poetry。

#!/usr/bin/env bash
# exit on error
set -o errexit

pip install --upgrade pip; pip install poetry;  # 重新安装一下最新的 Poetry,因为默认的 Poetry 的版本比较低。
poetry install

python manage.py collectstatic --no-input
python manage.py migrate
Code language: PHP (php)

render.yml

Render 当中,最重要的是 startCommandPYTHON_VERSION ,startCommand 这里是我使用 gunicorn 来启动 Django 应用,而 PYTHON_VERSION 则是用来设定具体的 Python 版本,这里我根据我自己的需求,选择了 Python 3.11.4。

databases:
  - name: linuxondjango-db
    databaseName: mysite
    user: mysite
    plan: free

services:
  - type: web
    name: linuxondjango
    plan: free
    runtime: python
    buildCommand: "./build.sh"
    startCommand: "gunicorn linuxondjango.wsgi:application"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: linuxondjango-db
          property: connectionString
      - key: SECRET_KEY
        generateValue: true
      - key: WEB_CONCURRENCY
        value: 4
      - key: PYTHON_VERSION # 这里的 python version 是用来指定 Python 版本的,比如这里我用的是 3.11.4。
        value: 3.11.4
Code language: PHP (php)

总结

Render 的教程总体来说没啥大问题,但是在一些小的点上,需要你自己简单 Hack 一下,比如需要自己升级一下 Poetry、设定 Python 版本。如果你也在用高版本的 Django & Render,希望这篇文章 可以帮到你。

flat screen monitor

如何解决 Kindle 在 M1 系列设备上无法访问的问题

问题

在使用 M1 的时候,我遇到一个很麻烦的问题是 M1 无法识别出我的 Kindle系统无法自动加载 M1 设备,这导致习惯于导入标注并使用 Klib 管理的我来说,等于用 Kindle 的功能不齐全了。

使用 macOS 自带的系统工具,也可以看到系统 Kindle 的磁盘,但无法加载。

d2b5ca33bd970f64a6301fa75ae2eb22 29
磁盘工具的展示

如果使用磁盘工具尝试加载,也会报错 com.apple.DiskManagement.disenter错误-119930872

d2b5ca33bd970f64a6301fa75ae2eb22 30
报错的提示

无法使用系统工具加载。

解决方案

在参考了 jakevin 的分享后,我使用如下方式来解决我的 Kindle 挂载问题。

查询外置设备

执行如下命令,可以使用系统自带的 diskutil 查看目前有哪些磁盘。我在这里补充了 grep,来筛选出只有外置磁盘的设备。

diskutil list | grep external -A2
Code language: PHP (php)
d2b5ca33bd970f64a6301fa75ae2eb22 31

手动挂载设备

执行如下命令,来手动挂载 Kindle。

sudo mkdir /Volumes/Kindle # 创建一个新的挂载点,挂载 Kindle
sudo mount -t msdos /dev/disk4 /Volumes/Kindle/ # 使用 mount 命令,挂载 /dev/disk4(你根据需要换成你自己的设备。)
Code language: PHP (php)

一般来说, Kindle 的默认格式化是 fat32 格式,所以用上面的命令就行,但如果你的 Kindle 是 ex-fat 格式,则可以使用如下命令挂载。

sudo /sbin/mount_exfat /dev/disk4 /Volumes/Kindle/ #这里使用的是 mount_exfat。
Code language: PHP (php)

如此操作,便可以让 M1 识别 Kindle 了。

d2b5ca33bd970f64a6301fa75ae2eb22 32