
Vokabry - Learn Vocabulary with AI
Learn vocabulary with AI assistance
岗位要求
简历投递方式
请将简历发送到 [email protected],标题注明“高级后端工程师 - 姓名”。
更多信息
欢迎大家也分享自己的年总结和新年计划!
很惭愧,我的新年目标是去年没完成的那几个……
不过今年还多了两个年度挑战 ![]()
修改:
为同一个URL规则指定多个视图函数
SQLITE_PATH = Path(__file__).resolve() / 'data.db'
修改:
SQLITE_PATH = Path(__file__).resolve().parent / 'data.db'
]]>from faker import Faker import random
]]>Optional 会自动设置 nullable,不用额外设置):
author_id: Mapped[Optional[int]] = mapped_column(ForeignKey(‘author.id’))
也可以先不提交会话,等设置了双向关系以后再 commit。
]]>P160 页 表格 5-7
paginate 第一个参数是 statement 吧?我看写得是 select。
我用 statement 比如:stmt = select(Note) 测试了下,符合我想要的。
这里是指参数名是 select。
是指用模型类名获取对应元素。这里 notes[0]['Note'] 写错了,应该是 notes[0]._mapping['Note']
P164 这里是出版社校对的时候乱改,导致偏离了原来的意思。我的原始书稿里是这样写的:
第一版就有很多被乱改的地方,而且也没有跟我确认。
确认的几处已经更新到勘误表,感谢反馈!
]]>request.files.get 和 request.files.getlist 来获取文件参数。
欢迎大家 CR :
]]>SQLITE_PATH = Path(__file__).resolve() / 'db.sqlite'
应该为
SQLITE_PATH = Path(__file__).parent.resolve() / 'db.sqlite'
否则会得到错误的文件路径
>>> db
<SQLAlchemy sqlite:////Users/zhangkaiqiang/PycharmProjects/notebook/app.py/db.sqlite>
导致 db.create_all() 等方法报错
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
(Background on this error at: https://sqlalche.me/e/20/e3q8)
GitHub 仓库中给出代码正确。
]]>class Author(db.Model):
__tablename__ = 'author'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(20))
phone: Mapped[Optional[str]] = mapped_column(String(11))
articles: Mapped[list['Article']] = relationship(back_populates='author')
def __repr__(self):
return f'<Author {self.id}: {self.name}>'
class Article(db.Model):
__tablename__ = 'article'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(50))
body: Mapped[str] = mapped_column(Text)
author_id: Mapped[int] = mapped_column(ForeignKey('author.id'))
author: Mapped['Author'] = relationship(back_populates='articles')
def __repr__(self):
return f'<Article {self.id}: {self.title}>'
下文中创建 Author 和 Article 记录不能正确执行,因为没有建立 Author 和 Article 的逻辑关系:
>>> richard = Author(name='Richard')
>>> eggs = Article(title='Eggs', body='blah...')
>>> snake = Article(title='Snake', body='blah...')
>>> db.session.add_all([richard, eggs, snake])
>>> db.session.commit()
报错如下:
```python
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: article.author_id
[SQL: INSERT INTO article (id, author_id, title, body) VALUES (?, ?, ?, ?), (?, ?, ?, ?)]
[parameters: ('b1c35814fbd24672b2d9d207393640a6', None, 'Eggs', 'blah...', '8aa059e967ae43679a697c7868e97d70', None, 'Snake', 'blah...')]
(Background on this error at: https://sqlalche.me/e/20/gkpj)
]]>paginate 第一个参数是 statement 吧?我看写得是 select。
我用 statement 比如:stmt = select(Note) 测试了下,符合我想要的。
供参考
P161 页
书上注释:#按名称获取元素 的意思是?
我试了下,元组不能被用文本切片,是我哪里弄错了么?
>>> notes
[(<Note 1 foo>,), (<Note 2 bar>,), (<Note 3 baz>,)]
>>> notes[0][0]
<Note 1 foo>
>>> notes[0]['Note']
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "lib/sqlalchemy/cyextension/resultproxy.pyx", line 54, in sqlalchemy.cyextension.resultproxy.BaseRow.__getitem__
TypeError: tuple indices must be integers or slices, not str
P164
第二排文字,类似于like(),但必须添加 % 是否是指 使用 like() 才需要添加 % 但是 contains() 不需要?
P164
表格中 endnswith 应该是 endswith 供参考
P168
代码:.values(Note.body=‘My body will be updated.’) 改成 values(body=‘My body will be updated’) 否则报错,供参考
另外,此代码块,最后仍需增加 db.session.commit() 才能提交生效 供参考
>>> stmt = (
... update(Note)
... .filter_by(id=2)
... .values(body='My body will be updated.'))
>>> db.session.execute(stmt)
<sqlalchemy.engine.cursor.CursorResult object at 0x0000028D5C357460>
>>> db.session.commit()
]]>
Learn vocabulary with AI assistance
现支持 MacOS + Windows,完全免费,欢迎大家下载试用、反馈
]]>class MyBaseForm(FlaskForm):
class Meta:
locales = ['zh']
可以运行,但是 IDE 里面 Meta下会有红波浪线,提示
“Meta”替代类“FlaskForm”中的同名符号
“pdm-playground.app.MyBaseForm.Meta”不可分配给“flask_wtf.form.FlaskForm.Meta”
类型“type[pdm-playground.app.MyBaseForm.Meta]”不可分配给类型“type[flask_wtf.form.FlaskForm.Meta]”PyrightreportIncompatibleVariableOverride
form.py(32, 11): 替代符号
AI 给改成显示继承:
class MyBaseForm(FlaskForm):
class Meta(FlaskForm.Meta):
locales = ['zh']
运行效果也是一样。
供参考
]]>__tablename = 'contacts'
是否应该是
__tablename__ = 'contacts'
供参考
]]>今年代码厨房准备了更多的贴纸,除了社区贴纸,还有本次几个开源松项目的 logo 贴纸,以及去年设计但忘记送的 Foobar 变量贴纸。
在展位上设计了两个活动,分别是「流浪记事本计划」和「开发者精神状态调查」。社区的本质是连接志同道合的人。在开源协作之外,这两个活动分别探索了用圆形贴纸和记事本作为连接媒介的可能。
流浪记事本的想法始于想在社区展位做一个留言本,后来想到不如让记事本自己去流浪,找到想写东西的人。
上午活动开始时,@frostming 作为第一棒带着本出发了。虽然最后接过笔记本的人没有按照提示归还,但我还是在主会场的最后一排找到了它:
大家在上面写了各种留言、涂鸦和笔记:
关于流浪记事本的整个故事和收集到的大部分留言可以在这篇文章看到。
我一直很好奇大家对待生活、工作和编程是什么样的态度,所以这个活动算是从满足自己的好奇心出发的。因为 A3 尺寸太小,调查问卷只设置了五个问题,参与者通过用贴纸贴到对应区域来回答问题。
最终吸引到大概 150 人参与投票:
虽然考虑到会有样本偏差(只采样线下来参加活动的人),而且还有一些干扰数据:
但还是没想到大家的精神状态那么健康:
开源松 Sprint 7 在分会场 E 举办(上海对外经贸大学贸源楼 106 教室),是一间很温馨(小)的教室(以至于后面很多人没能挤进来)。
这次开源松设置了 5 个项目:
下面是每个项目的路演视频:
幻灯片:slides/soos7 at main · codekitchen-community/slides · GitHub
按照惯例,这次开源松依然以代码厨房乐队演出结尾。演出由周煦林 @voidZXL 和卢书洋 @ZinkLu 带来:
演出录像:代码厨房 x PyCon 音乐会 @ PyCon China 2025
感谢所有来参与活动的朋友,期待下次再见!
想不想加入我们一起策划和举办下一场好玩的活动?欢迎填写下面的申请表单加入我们的志愿者团队——「厨房组委会」:
关注我们的社交网络获取动态更新:
本次开销由 @greyli 赞助:
另外感谢 @Farmer-Chillax 赞助的小鹏汽车模型玩具以及 PyCon China 赞助的鼠标垫。
本次开源松所有流程和物料设计都由 @greyli 完成。感谢 PyCon 组委会和上海对外经贸大学提供会务和场地支持,感谢志愿者们提供现场支持:
展位支持:高佳 @gaoshizhendegao、吴小朋、@Farmer-Chillax、@gaojingru
摄影摄像:雾雨魔理莎、Await
倒数第四行 编辑排版应该忘了空格了,flaskrun–help 应该是 flask run --help 吧?
]]>flask 在获取上传的文件参数时,有两种方式:
request.filesrequest.files.getlist如果使用 request.files :
如果使用 request.files.getlist :
也就是说,获取到的参数的类型仅与获取参数的方式相关,而和这个参数在被上传时,是单文件上传还是多文件上传无关。故无法判断客户端的初始意图是上传单文件还是文件列表。在将参数转换为 Pydantic 模型时,也无法将文件参数类型进行精确匹配,因为无法知悉其到底是文件类型还是文件列表类型(如上所述,这仅取决于获取参数的方式,无法判断客户端的初始意图是什么)。
也许还有其他什么我尚不知晓的获取文件参数的方式?或者大家有什么其他的想法或思路可以处理这个问题?
欢迎大家留言讨论,不胜感激。
以下是最小演示示例:
app.py
from flask import Flask, request
from werkzeug.datastructures import FileStorage
app = Flask(__name__)
@app.route('/upload', methods=['POST'])
def upload_file():
# 单文件
assert isinstance(request.files['single_file'], FileStorage)
assert request.files['single_file'].filename == 'test.txt'
# 使用 request.files.getlist 即使是单文件也会返回一个 list
assert isinstance(request.files.getlist('single_file'), list)
assert len(request.files.getlist('single_file')) == 1
# list 中只有一个元素,就是这个单文件
assert request.files.getlist('single_file')[0].filename == 'test.txt'
# 多文件
assert isinstance(request.files.getlist('multi_files'), list)
assert len(request.files.getlist('multi_files')) == 3
# 使用 request.files 会获取到列表的首个文件
assert isinstance(request.files['multi_files'], FileStorage)
# 以下这个断言会概率性失败,因为 list 中文件的顺序和上传顺序并不一定一致
# assert request.files.getlist('multi_files')[0].filename == 'test1.txt'
# 但通过 request.files 获取的一定是 list 的首个文件
assert request.files['multi_files'].filename == request.files.getlist('multi_files')[0].filename
return {"message": "Passed"}
requests客户端:
import requests
rv = requests.post(
"http://localhost:5000/upload",
files={
("single_file", ("test.txt", open("test.txt", "rb"), "text/plain")),
("multi_files", ("test1.txt", open("test1.txt", "rb"), "text/plain")),
("multi_files", ("test2.txt", open("test2.txt", "rb"), "text/plain")),
("multi_files", ("test3.txt", open("test3.txt", "rb"), "text/plain")),
},
)
版本信息:
flask: 3.1.2
requests: 2.32.5
另外话题也可以嘉宾自己定,你有啥想聊的方向吗?
]]>请问后面计划聊什么话题呢?
]]>有人建社区、搞乐队、组织开源松,也有人默默在做点理想的事。
「#代码厨房播客」第一期上线!
主持人 苏雄 对话 李辉(Grey) ——
Flask 团队成员、《Flask Web 开发实战》作者、「代码厨房」社区发起人。
他们聊了:
非盈利技术社区如何运作?
为什么程序员也需要“共情力”?
技术书出版的坑与经验分享
从“理想主义”到“流程自动化”的平衡
一句话概括:
这是一期程序员之间关于理想、执行与温度 的长谈。
在各大平台搜索「代码厨房播客」收听吧!
感谢 @uncle-lv @Farmer-Chillax @tyang.sh3 参与贡献!
]]>不过后面还要再来好好优化这部分代码。欢迎大家帮忙测试!
]]>### Feature Description Now PDM startup is still very slow, most of the time is…
有兴趣可以来贡献
]]>如果有兴趣,可以看看我整理的日语学习资料:
]]>网站地址:
实机演示:
简单来说,其实就是一个「导航页」,但和一般的搜索导航站相比,「易查」不仅支持自定义,而且还多了一步「分析搜索结果」——判断对应网站是否存在有意义的搜索结果,并将结果显示在页面上。
另外还(会)实现一些功能:
由于还处在早期开发阶段,所以现在每次查询会把20多个网站在服务器挨个打开一遍,看那些网站返回的结果有没有指定的关键字,所以速度会非常慢,这个网页暂时当做最后的备用手段吧2333。
之后我会结合用户反馈,把一些较为常用的搜索词的结果整理到数据库,访问起来就会快得多了,但具体哪些网站和哪些词,我想看看大家的建议。
另外,公开一份我自己维护的在线辞典网站,学日语和英语的话,可以看看:
]]>.git/objects/pack目录下了。
通过git verify-pack -v命令可以查看到这条commit的对象:
StackOverflow相关问答: object directory has no objects after a git clone
]]>谢谢各位大佬!![]()