从零开始:使用 Flask 或 Django 构建 RESTful API

news/2024/10/20 10:44:19/

引言

在当今这个数据驱动的时代,构建高效、可扩展的后端服务变得尤为重要。RESTful API 作为一种设计模式,已经成为现代 Web 开发的标准之一。无论是小型初创公司还是大型企业,都需要一个强大的后端来支持前端应用的快速迭代和用户需求的变化。Flask 和 Django 是 Python 生态中最受欢迎的两个 Web 框架,它们都可以用来构建 RESTful API。本文将详细介绍如何使用这两个框架来构建 RESTful API,并通过实例帮助你理解其核心概念和实际应用。

基础语法介绍

什么是 RESTful API?

REST(Representational State Transfer)是一种软件架构风格,它定义了一组约束条件和架构原则。RESTful API 是基于这些原则设计的 Web 服务接口,通常使用 HTTP 协议进行通信。RESTful API 的核心特性包括:

  • 无状态性:每个请求都必须包含所有必要的信息,服务器不会保存任何会话状态。
  • 统一接口:使用标准的 HTTP 方法(GET、POST、PUT、DELETE 等)来操作资源。
  • 资源导向:API 的 URL 应该指向资源,而不是操作。

Flask vs Django

Flask

Flask 是一个轻量级的 Web 框架,非常适合快速开发和小型项目。它的核心非常简单,但可以通过扩展来添加更多功能。Flask 的灵活性使得它可以适应各种不同的应用场景。

Django

Django 是一个全栈框架,提供了丰富的功能和工具,适合大型项目和企业级应用。Django 内置了 ORM、认证系统、管理后台等,可以大大减少开发时间和工作量。

核心概念

  • 路由:定义 URL 与视图函数之间的映射关系。
  • 视图:处理请求并返回响应。
  • 模型:表示数据库中的数据结构。
  • 序列化器:将模型对象转换为 JSON 格式,以便通过 API 返回。

基础实例

使用 Flask 构建 RESTful API

问题描述

假设我们需要构建一个简单的 API 来管理用户的个人信息。用户可以创建、读取、更新和删除自己的信息。

代码示例

首先,安装 Flask 和 Flask-RESTful:

pip install Flask Flask-RESTful

然后,创建一个简单的 Flask 应用:

from flask import Flask, request
from flask_restful import Resource, Apiapp = Flask(__name__)
api = Api(app)# 模拟数据库
users = {}class UserResource(Resource):def get(self, user_id):if user_id in users:return users[user_id], 200else:return {"message": "User not found"}, 404def post(self, user_id):if user_id in users:return {"message": "User already exists"}, 400else:data = request.get_json()users[user_id] = datareturn data, 201def put(self, user_id):if user_id in users:data = request.get_json()users[user_id].update(data)return users[user_id], 200else:return {"message": "User not found"}, 404def delete(self, user_id):if user_id in users:del users[user_id]return {"message": "User deleted"}, 200else:return {"message": "User not found"}, 404api.add_resource(UserResource, '/users/<string:user_id>')if __name__ == '__main__':app.run(debug=True)

使用 Django 构建 RESTful API

问题描述

同样的场景,我们使用 Django 来构建一个用户管理的 API。

代码示例

首先,安装 Django 和 Django REST framework:

pip install Django djangorestframework

然后,创建一个新的 Django 项目和应用:

django-admin startproject myproject
cd myproject
python manage.py startapp myapp

编辑 myapp/models.py 文件,定义用户模型:

from django.db import modelsclass User(models.Model):name = models.CharField(max_length=100)email = models.EmailField(unique=True)def __str__(self):return self.name

编辑 myapp/serializers.py 文件,定义序列化器:

from rest_framework import serializers
from .models import Userclass UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['id', 'name', 'email']

编辑 myapp/views.py 文件,定义视图:

from rest_framework import viewsets
from .models import User
from .serializers import UserSerializerclass UserViewSet(viewsets.ModelViewSet):queryset = User.objects.all()serializer_class = UserSerializer

编辑 myapp/urls.py 文件,定义路由:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserViewSetrouter = DefaultRouter()
router.register(r'users', UserViewSet)urlpatterns = [path('', include(router.urls)),
]

最后,编辑 myproject/urls.py 文件,包含应用的路由:

from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('api/', include('myapp.urls')),
]

运行迁移命令以创建数据库表:

python manage.py migrate

启动 Django 开发服务器:

python manage.py runserver

现在,你可以通过访问 http://127.0.0.1:8000/api/users/ 来测试 API。

进阶实例

使用 Flask 构建复杂的 RESTful API

问题描述

假设我们需要构建一个更复杂的 API,支持分页、过滤和排序功能。

高级代码实例

首先,安装 Flask-SQLAlchemy 和 Flask-Marshmallow:

pip install Flask-SQLAlchemy Flask-Marshmallow marshmallow-sqlalchemy

然后,创建一个 Flask 应用:

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallowapp = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db = SQLAlchemy(app)
ma = Marshmallow(app)# 定义用户模型
class User(db.Model):id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(100))email = db.Column(db.String(100), unique=True)# 定义序列化器
class UserSchema(ma.SQLAlchemyAutoSchema):class Meta:model = Useruser_schema = UserSchema()
users_schema = UserSchema(many=True)@app.route('/users', methods=['GET'])
def get_users():query = User.queryname = request.args.get('name')if name:query = query.filter(User.name.contains(name))sort_by = request.args.get('sort_by', 'name')sort_order = request.args.get('sort_order', 'asc')if sort_order == 'desc':query = query.order_by(getattr(User, sort_by).desc())else:query = query.order_by(getattr(User, sort_by))page = request.args.get('page', 1, type=int)per_page = request.args.get('per_page', 10, type=int)paginated_users = query.paginate(page, per_page, error_out=False)return users_schema.jsonify(paginated_users.items)@app.route('/users', methods=['POST'])
def create_user():data = request.get_json()new_user = User(name=data['name'], email=data['email'])db.session.add(new_user)db.session.commit()return user_schema.jsonify(new_user), 201@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):user = User.query.get_or_404(user_id)data = request.get_json()user.name = data.get('name', user.name)user.email = data.get('email', user.email)db.session.commit()return user_schema.jsonify(user)@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):user = User.query.get_or_404(user_id)db.session.delete(user)db.session.commit()return '', 204if __name__ == '__main__':db.create_all()app.run(debug=True)

使用 Django 构建复杂的 RESTful API

问题描述

同样的场景,我们使用 Django 来构建一个支持分页、过滤和排序的 API。

高级代码实例

首先,安装 Django-Filter:

pip install django-filter

然后,编辑 myapp/filters.py 文件,定义过滤器:

import django_filters
from .models import Userclass UserFilter(django_filters.FilterSet):name = django_filters.CharFilter(lookup_expr='icontains')class Meta:model = Userfields = ['name', 'email']

编辑 myapp/views.py 文件,定义视图:

from rest_framework import filters
from .models import User
from .serializers import UserSerializer
from .filters import UserFilterclass UserViewSet(viewsets.ModelViewSet):queryset = User.objects.all()serializer_class = UserSerializerfilter_backends = [filters.SearchFilter, filters.OrderingFilter, django_filters.rest_framework.DjangoFilterBackend]filterset_class = UserFiltersearch_fields = ['name', 'email']ordering_fields = ['name', 'email']

现在,你可以通过访问 http://127.0.0.1:8000/api/users/?name=John&sort_by=name&sort_order=desc&page=1&per_page=10 来测试 API。

实战案例

项目背景

假设你在一个电商平台上工作,需要构建一个 API 来管理商品信息。商品信息包括名称、描述、价格、库存等。你需要支持商品的增删改查操作,并且提供分页、过滤和排序功能。

问题描述

  • 商品信息需要存储在数据库中。
  • API 需要支持分页、过滤和排序功能。
  • 需要处理并发请求,保证数据的一致性。

解决方案

使用 Flask 构建 API
  1. 模型定义:定义商品模型,使用 SQLAlchemy 作为 ORM。
  2. 序列化器:使用 Flask-Marshmallow 将模型对象转换为 JSON 格式。
  3. 视图函数:定义处理请求的视图函数,支持分页、过滤和排序。
  4. 并发处理:使用 Flask-SQLAlchemy 的事务管理功能,保证数据的一致性。
代码实现
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallowapp = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///products.db'
db = SQLAlchemy(app)
ma = Marshmallow(app)# 定义商品模型
class Product(db.Model):id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(100))description = db.Column(db.String(500))price = db.Column(db.Float)stock = db.Column(db.Integer)# 定义序列化器
class ProductSchema(ma.SQLAlchemyAutoSchema):class Meta:model = Productproduct_schema = ProductSchema()
products_schema = ProductSchema(many=True)@app.route('/products', methods=['GET'])
def get_products():query = Product.queryname = request.args.get('name')if name:query = query.filter(Product.name.contains(name))sort_by = request.args.get('sort_by', 'name')sort_order = request.args.get('sort_order', 'asc')if sort_order == 'desc':query = query.order_by(getattr(Product, sort_by).desc())else:query = query.order_by(getattr(Product, sort_by))page = request.args.get('page', 1, type=int)per_page = request.args.get('per_page', 10, type=int)paginated_products = query.paginate(page, per_page, error_out=False)return products_schema.jsonify(paginated_products.items)@app.route('/products', methods=['POST'])
def create_product():data = request.get_json()new_product = Product(name=data['name'], description=data['description'], price=data['price'], stock=data['stock'])db.session.add(new_product)db.session.commit()return product_schema.jsonify(new_product), 201@app.route('/products/<int:product_id>', methods=['PUT'])
def update_product(product_id):product = Product.query.get_or_404(product_id)data = request.get_json()product.name = data.get('name', product.name)product.description = data.get('description', product.description)product.price = data.get('price', product.price)product.stock = data.get('stock', product.stock)db.session.commit()return product_schema.jsonify(product)@app.route('/products/<int:product_id>', methods=['DELETE'])
def delete_product(product_id):product = Product.query.get_or_404(product_id)db.session.delete(product)db.session.commit()return '', 204if __name__ == '__main__':db.create_all()app.run(debug=True)
使用 Django 构建 API
  1. 模型定义:定义商品模型,使用 Django 的 ORM。
  2. 序列化器:使用 Django REST framework 将模型对象转换为 JSON 格式。
  3. 视图集:定义处理请求的视图集,支持分页、过滤和排序。
  4. 并发处理:使用 Django 的事务管理功能,保证数据的一致性。
代码实现

编辑 myapp/models.py 文件,定义商品模型:

from django.db import modelsclass Product(models.Model):name = models.CharField(max_length=100)description = models.TextField()price = models.DecimalField(max_digits=10, decimal_places=2)stock = models.IntegerField()def __str__(self):return self.name

编辑 myapp/serializers.py 文件,定义序列化器:

from rest_framework import serializers
from .models import Productclass ProductSerializer(serializers.ModelSerializer):class Meta:model = Productfields = ['id', 'name', 'description', 'price', 'stock']

编辑 myapp/filters.py 文件,定义过滤器:

import django_filters
from .models import Productclass ProductFilter(django_filters.FilterSet):name = django_filters.CharFilter(lookup_expr='icontains')class Meta:model = Productfields = ['name', 'price', 'stock']

编辑 myapp/views.py 文件,定义视图集:

from rest_framework import filters
from .models import Product
from .serializers import ProductSerializer
from .filters import ProductFilterclass ProductViewSet(viewsets.ModelViewSet):queryset = Product.objects.all()serializer_class = ProductSerializerfilter_backends = [filters.SearchFilter, filters.OrderingFilter, django_filters.rest_framework.DjangoFilterBackend]filterset_class = ProductFiltersearch_fields = ['name', 'description']ordering_fields = ['name', 'price', 'stock']

编辑 myapp/urls.py 文件,定义路由:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSetrouter = DefaultRouter()
router.register(r'products', ProductViewSet)urlpatterns = [path('', include(router.urls)),
]

编辑 myproject/urls.py 文件,包含应用的路由:

from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('api/', include('myapp.urls')),
]

运行迁移命令以创建数据库表:

python manage.py migrate

启动 Django 开发服务器:

python manage.py runserver

现在,你可以通过访问 http://127.0.0.1:8000/api/products/?name=Apple&sort_by=price&sort_order=desc&page=1&per_page=10 来测试 API。

扩展讨论

性能优化

  • 缓存:使用缓存技术(如 Redis)来减少数据库查询次数,提高响应速度。
  • 异步处理:使用异步任务队列(如 Celery)来处理耗时的任务,如发送邮件、生成报表等。
  • 负载均衡:使用负载均衡器(如 Nginx)来分散请求,提高系统的可用性和性能。

安全性

  • 身份验证:使用 JWT 或 OAuth2 进行身份验证,确保只有授权用户才能访问敏感数据。
  • 输入验证:对用户输入进行严格的验证,防止 SQL 注入、XSS 攻击等安全漏洞。
  • 日志记录:记录关键操作的日志,便于问题排查和审计。

部署与运维

  • 容器化:使用 Docker 容器化应用,简化部署和运维。
  • 持续集成/持续部署:使用 CI/CD 工具(如 Jenkins、GitHub Actions)自动化测试和部署流程。
  • 监控与报警:使用监控工具(如 Prometheus、Grafana)实时监控应用的状态,及时发现和解决问题。

社区与资源

  • 官方文档:Flask 和 Django 的官方文档是非常好的学习资源,建议深入阅读。
  • 社区论坛:Stack Overflow、Reddit 等社区有很多开发者分享经验和解决问题的方法。
  • 开源项目:GitHub 上有很多优秀的开源项目,可以参考和学习。

http://www.ppmy.cn/news/1540494.html

相关文章

DNS安全检测与防护策略

DNS在互联网基础服务中&#xff0c;负责将域名转换为IP地址&#xff0c;但是随网络的演变&#xff0c;DNS系统面临安全方面的威胁也有增多&#xff0c;比如DNS劫持、缓存中毒、域名欺骗等。 ※为什么要看重DNS的安全检测&#xff1f; 因为DNS一旦遭受攻击&#xff0c;将直接影…

极氪汽车困局:营销频繁车、产品力不足

“ 极氪汽车的“车上吃火锅”营销活动虽登上热搜&#xff0c;但因频繁忽视老用户和产品力不足的争议&#xff0c;并未赢得消费者好感&#xff0c;反而加剧负面印象。 ” 科技新知 原创 作者丨颜瞾 编辑丨蕨影 近日&#xff0c;背靠吉利集团的极氪…

LLM:参数高效微调方法总结

可以分为基于适配器、基于提示的。 一、基于适配器的方法 其核心思想是在预训练模型的各层之间插入轻量级的额外模块——适配器&#xff0c;通过仅微调这些适配器模块以适应特定的下游任务&#xff0c;同时冻结原模型的大部分参数。 1.Lora系列 原始的Lora LoRA 表示通过低…

国外电商系统开发-运维系统应用管理

还记得您常用的 service httpd start 、service sshd stop这样的命令吗&#xff1f;这些都是在停止启动服务&#xff0c;为了让研发人员&#xff0c;或者是快速操作服务&#xff0c;这里给大家制定了简单的应用管理。在这里&#xff0c;您可以把上面的命令加入进来&#xff0c;…

二叉树算法之B+ 树(B+ Tree)详细解读

B树&#xff08;B Tree&#xff09;是B树的一种变体&#xff0c;广泛应用于数据库系统和文件系统的索引结构。与B树相比&#xff0c;B树在结构上有一些改进&#xff0c;特别是在提高查询效率、范围查找性能和磁盘I/O效率等方面更具优势。 1. B树的定义与性质 B树与B树的主要区…

微信小程序中的文件查看方法

获得后缀名判断类型,如果是图片用ex.previewImage(),如果是视频,用uni.previewMedia(),如果是word文档这些的,用 uni.downloadFile来下载资源后用 uni.saveFile来保存到本地,uni.openDocument来打开新的网页,如果打不开的话则返回说到PC端去打开 const lookFile (url) > {l…

Gin框架操作指南03:HTML渲染

官方文档地址&#xff08;中文&#xff09;&#xff1a;https://gin-gonic.com/zh-cn/docs/ 注&#xff1a;本教程采用工作区机制&#xff0c;所以一个项目下载了Gin框架&#xff0c;其余项目就无需重复下载&#xff0c;想了解的读者可阅读第一节&#xff1a;Gin操作指南&#…

pdf文件怎样一张纸打印四页

在日常工作和学习中&#xff0c;我们经常会遇到需要将PDF文件中的多页内容合并打印到一张纸上的情况&#xff0c;比如将四页内容打印到一张A4纸上&#xff0c;以节省纸张和成本。同时&#xff0c;在打开pdf文件的方式&#xff0c;一般都是通过电脑浏览器打印&#xff0c;因此对…