
Sign up to save your podcasts
Or


Datetime naive không gắn múi giờ là nguyên nhân của nhiều lỗi lệch giờ khó bắt: không chuyển đổi được đáng tin cậy, và so sánh với datetime aware sẽ ném lỗi ngay. Trong tập này, Linh Fish Dev Podcast #23 giải thích vì sao không bao giờ nên cộng trừ giờ bằng tay, và cách dùng module zoneinfo có sẵn từ Python 3.9 để luôn lưu thời gian ở UTC rồi chỉ chuyển sang giờ địa phương khi hiển thị bằng astimezone. Nghe xong, bạn sẽ có một quy ước duy nhất áp dụng được ngay cho database, API, log và job chạy định kỳ.
Python: xử lý múi giờ đúng bằng zoneinfo — hết lỗi naive/aware trong 5 phút
Nghe Linh Fish Dev Podcast trên:
Tập 22: Python thay chuỗi if/elif dài bằng match statement — pattern matching trong 5 phút. Chuỗi if/elif phân loại mã trạng thái hay loại sự kiện càng dài càng dễ sót nhánh, và khi giá trị cần phân loại là một dict lệnh từ API thì việc kiểm tra từng khóa bằng tay khiến code lồng nhau khó đọc. Match statement, có từ Python 3.10, so khớp giá trị với các mẫu theo thứ tự, gộp nhiều giá trị bằng dấu |, trích biến ngay trong mẫu dict và thêm điều kiện phụ bằng guard. Tập này giải thích vì sao match gọn hơn if/elif, ba lưu ý quan trọng — không fallthrough, mẫu cụ thể trước mẫu chung sau, luôn viết case _ — và khi nào vẫn nên giữ if/elif cho điều kiện dạng khoảng giá trị phức tạp.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: Python: thay chuỗi if/elif dài bằng match statement — pattern matching trong 5 phút
Nghe Linh Fish Dev Podcast trên:
Tập 21: FastAPI validate tham số đường dẫn bằng Path() — chặn ID sai ngay từ cổng API trong 5 phút. FastAPI tự chuyển tham số đường dẫn sang đúng kiểu, nhưng chỉ kiểm tra kiểu thì chưa đủ: /items/0 hay /items/-3 vẫn lọt qua dù ID trong database không bao giờ âm hay bằng 0. Dùng Path() với ge, le hoặc pattern, FastAPI chặn giá trị sai bằng lỗi 422 ngay từ cổng API, trước khi code chạm tới database. Tập này giải thích vì sao cổng API cần đặt luật cho chính tham số của nó, cách dùng Path() cho ID số và username dạng chuỗi, và điểm cần nhớ: Path() chỉ kiểm tra hình thức, việc bản ghi có tồn tại vẫn thuộc về tầng database với lỗi 404.
FastAPI: validate tham số đường dẫn bằng Path() — chặn ID sai ngay từ cổng API trong 5 phút
Nghe Linh Fish Dev Podcast trên:
Tập 20: FastAPI gắn request-id và đo thời gian xử lý cho mọi request bằng middleware tự viết trong 5 phút. Khi một request lỗi ở production mà không có mã định danh, việc đối chiếu log chẳng khác nào mò kim đáy bể — và đo thời gian trong từng endpoint thì vừa lặp code vừa thiếu nhất quán. Giải pháp là một middleware BaseHTTPMiddleware duy nhất: giữ nguyên X-Request-ID client gửi lên hoặc tự sinh UUID, bấm giờ bằng time.perf_counter, rồi gắn lại hai header X-Request-ID và X-Process-Time cho mọi response. Tập này giải thích vì sao thứ tự add_middleware quan trọng, vì sao perf_counter đúng hơn time.time, và khi nào nên chuyển sang middleware ASGI thuần cho response streaming lớn.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: FastAPI: gắn request-id và đo thời gian xử lý cho mọi request bằng middleware tự viết trong 5 phút
Nghe Linh Fish Dev Podcast trên:
Tập 19: Django REST Framework thêm endpoint tùy chỉnh bằng @action — khỏi tạo ViewSet mới trong 5 phút. Một ModelViewSet chỉ có sẵn năm thao tác CRUD, nên khi cần thêm nút xuất bản hay danh sách bài nổi bật, nhiều người viết thêm APIView riêng rồi đăng ký route bằng tay — permission và serializer phải viết lại, logic của cùng một tài nguyên bị xé ra hai nơi. Giải pháp là gắn decorator @action lên method ngay trong ViewSet: detail=True cho thao tác trên một object như publish, detail=False cho thao tác trên danh sách như featured, framework tự sinh route và giữ nguyên permission, serializer, queryset của ViewSet. Hai chi tiết hay bị quên: action chỉ đọc dùng method get, action đổi dữ liệu dùng post, patch hoặc delete cho đúng ngữ nghĩa, và truyền url_path vào decorator khi tên method không hợp làm đường dẫn.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: Django REST Framework: thêm endpoint tùy chỉnh bằng @action, khỏi tạo ViewSet mới trong 5 phút
Nghe Linh Fish Dev Podcast trên:
Tập 18: Django cache kết quả truy vấn bằng cache framework trong 5 phút — khỏi truy vấn lại mỗi request. Nhiều view Django chạy lại cùng một truy vấn ở mọi request dù dữ liệu hiếm khi thay đổi, khiến database chịu tải vô ích và trang chậm dần khi traffic tăng. Giải pháp là cache framework có sẵn của Django: lấy từ cache trước bằng cache.get, chưa có thì truy vấn rồi lưu lại bằng cache.set hoặc gọn hơn bằng get_or_set với timeout 300 giây, và chủ động xóa key cũ bằng cache.delete ngay khi dữ liệu đổi. Backend LocMemCache chỉ phù hợp phát triển và kiểm thử vì mỗi worker có một bản cache riêng; lên production, đổi sang Redis hoặc Memcached trong CACHES mà không cần sửa code dùng cache. Khi áp dụng, bắt đầu từ dữ liệu đọc nhiều, viết ít như danh mục sidebar, đặt timeout khoảng 5 phút và đo lại bằng django-debug-toolbar để thấy số query giảm thực tế.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: Django: cache kết quả truy vấn bằng cache framework trong 5 phút — khỏi truy vấn lại mỗi request
Nghe Linh Fish Dev Podcast trên:
Tập 17: Python thay os.path bằng pathlib — đọc, ghi và duyệt file gọn hơn trong 5 phút. Với os.path, đường dẫn chỉ là chuỗi ký tự: bạn phải nhớ đúng thứ tự đối số của join, tự lo dấu phân cách, và một thao tác đơn giản cũng cần kết hợp nhiều hàm rời rạc, lại dễ lệch giữa Windows và Linux. Giải pháp là đối tượng Path của pathlib: nối đường dẫn bằng toán tử gạch chéo, các thao tác kiểm tra tồn tại, tạo thư mục, tìm file bằng glob, đọc và ghi file nằm ngay trên chính đối tượng, cùng một đoạn code chạy được cả hai hệ điều hành. Ngoài ra còn có duyệt đệ quy, đổi đuôi file, lấy đường dẫn tương đối và chuẩn hóa thành đường dẫn tuyệt đối. Khi áp dụng, đừng đổi cả codebase một lúc: bắt đầu từ script mới hoặc đoạn khó đọc nhất, thay từng chỗ bằng Path, chạy lại một lần để chắc chắn kết quả không đổi, và chuyển Path thành chuỗi ngay tại biên nếu hàm cũ bắt buộc nhận chuỗi.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: Python: thay os.path bằng pathlib — đọc, ghi và duyệt file gọn hơn trong 5 phút
Nghe Linh Fish Dev Podcast trên:
Pocket Casts
Tập 16: FastAPI đọc header và cookie bằng Header() và Cookie() trong 5 phút. Bạn sẽ nghe vì sao cách moi request thủ công hay gặp ba điểm yếu: tên header không phân biệt hoa thường nên dễ gõ sai, không có validate nên giá trị sai chỉ lộ ra ở tầng xử lý sâu, và mỗi endpoint lặp lại đoạn moi và kiểm tra giống nhau. Giải pháp là khai báo Header() và Cookie() ngay trong chữ ký hàm: FastAPI tự trích xuất, tự validate, trả lỗi 422 rõ ràng khi thiếu hoặc sai kiểu. Quy tắc đặt tên cũng rất gọn: tham số x_request_id tự đổi thành header X-Request-ID, tên cookie giữ nguyên, có giá trị mặc định None là tùy chọn, không có mặc định là bắt buộc. Bạn còn nhớ thêm hai trường hợp đặc biệt: dùng alias khi tên header không đặt được thành tên biến Python, và cookie HttpOnly vẫn đọc được bằng Cookie() vì HttpOnly chỉ chặn JavaScript phía trình duyệt, không chặn server.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: FastAPI: đọc header và cookie bằng Header() và Cookie() trong 5 phút — khỏi moi request thủ công
Nghe Linh Fish Dev Podcast trên:
Tập 15: Flask cho phép tải file an toàn bằng send_file và send_from_directory trong 5 phút. Bạn sẽ nghe vì sao cách viết tay hay mắc hai lỗi cùng lúc: nối thẳng tên file từ URL vào đường dẫn nên kẻ xấu chèn ../ là thoát khỏi thư mục cho phép, và đọc hết file vào RAM trước khi trả về nên file càng lớn server càng nặng. Giải pháp là send_from_directory cho file đã có sẵn trong thư mục, với safe_join của Werkzeug chặn path traversal và trả 404 khi đường dẫn thoát ra ngoài, cùng as_attachment và download_name để ép tải xuống đúng tên file. Với file tạo ra trong lúc chạy như báo cáo CSV, dùng send_file với đối tượng file trong bộ nhớ và stream từng phần. Quy tắc chọn chỉ một câu: file sẵn trong thư mục thì send_from_directory, file tạo lúc chạy thì send_file — nhưng vẫn phải kiểm tra quyền sở hữu, giới hạn đuôi file và ghi log mỗi lượt tải.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: Flask: cho phép tải file an toàn bằng send_file và send_from_directory trong 5 phút
Nghe Linh Fish Dev Podcast trên:
Tập 14: Flask ghi log đúng cách bằng app.logger — thay print() trước khi lên production. Bạn sẽ nghe vì sao print() gần như vô dụng trên production: không timestamp, không phân biệt mức độ, log rải rác khi chạy nhiều worker, và đúng lúc crash thì dòng cuối có thể chưa kịp ghi ra. Giải pháp là app.logger có sẵn của Flask, thêm RotatingFileHandler xoay file ở 1 MB giữ 3 bản cũ, gắn formatter thời gian + mức độ, và dùng app.logger.exception() để ghi toàn bộ traceback trong khối except. Nhớ đặt mức INFO trên production, ghi log trước ở route thanh toán, đăng nhập và API bên ngoài, và tuyệt đối không ghi mật khẩu, token hay thông tin thẻ.
Đọc bài viết đầy đủ kèm code mẫu đã kiểm chứng chạy được tại: Flask: ghi log đúng cách bằng app.logger — thay print() trước khi lên production
Nghe Linh Fish Dev Podcast trên:
From the publisher's feed