当前位置: 首页 > news >正文

Django REST Framework 构建安卓应用后端API:从开发到部署的完整实战指南

本文将详细介绍如何使用 Django 和 Django REST Framework (DRF) 为安卓应用构建稳定、安全、高效的 RESTful API 接口。


第一阶段:项目基础设置

1.1 安装必要的包

pip install django djangorestframework django-cors-headers djangorestframework-simplejwt pillow

1.2 创建Django项目和应用

django-admin startproject backend
cd backend
python manage.py startapp api

1.3 配置 settings.py

# settings.py
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',# 第三方应用'rest_framework','rest_framework_simplejwt','corsheaders',# 自定义应用'api',
]# DRF 配置
REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',  # 默认需要认证),'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination','PAGE_SIZE': 20
}# JWT 配置
from datetime import timedelta
SIMPLE_JWT = {'ACCESS_TOKEN_LIFETIME': timedelta(days=1),'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
}# CORS 配置(允许安卓应用访问)
CORS_ALLOWED_ORIGINS = ["http://localhost:8080",        # 开发时安卓模拟器"http://192.168.1.100:8080",    # 本地网络地址"https://yourdomain.com",       # 生产域名
]CORS_ALLOW_CREDENTIALS = True# 允许所有域名访问(开发阶段,生产环境应限制)
# CORS_ALLOW_ALL_ORIGINS = TrueMIDDLEWARE = ['corsheaders.middleware.CorsMiddleware',  # 尽量放在最前'django.middleware.security.SecurityMiddleware',# ... 其他中间件
]

第二阶段:数据模型设计

2.1 定义核心模型(api/models.py)

from django.db import models
from django.contrib.auth.models import Userclass Category(models.Model):name = models.CharField(max_length=100)description = models.TextField(blank=True)created_at = models.DateTimeField(auto_now_add=True)def __str__(self):return self.nameclass Product(models.Model):name = models.CharField(max_length=200)description = models.TextField()price = models.DecimalField(max_digits=10, decimal_places=2)category = models.ForeignKey(Category, on_delete=models.CASCADE)image = models.ImageField(upload_to='products/', null=True, blank=True)stock = models.IntegerField(default=0)is_active = models.BooleanField(default=True)created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)def __str__(self):return self.nameclass UserProfile(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE)phone = models.CharField(max_length=15, blank=True)avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)address = models.TextField(blank=True)created_at = models.DateTimeField(auto_now_add=True)def __str__(self):return self.user.usernameclass Order(models.Model):STATUS_CHOICES = [('pending', '待处理'),('processing', '处理中'),('shipped', '已发货'),('delivered', '已送达'),('cancelled', '已取消'),]user = models.ForeignKey(User, on_delete=models.CASCADE)total_amount = models.DecimalField(max_digits=10, decimal_places=2)status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')shipping_address = models.TextField()created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)class OrderItem(models.Model):order = models.ForeignKey(Order, on_delete=models.CASCADE)product = models.ForeignKey(Product, on_delete=models.CASCADE)quantity = models.IntegerField()price = models.DecimalField(max_digits=10, decimal_places=2)

2.2 执行数据库迁移

python manage.py makemigrations
python manage.py migrate

第三阶段:序列化器创建

3.1 创建序列化器(api/serializers.py)

from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Category, Product, UserProfile, Order, OrderItemclass UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ('id', 'username', 'email', 'first_name', 'last_name')class UserProfileSerializer(serializers.ModelSerializer):user = UserSerializer(read_only=True)class Meta:model = UserProfilefields = '__all__'class CategorySerializer(serializers.ModelSerializer):class Meta:model = Categoryfields = '__all__'class ProductSerializer(serializers.ModelSerializer):category_name = serializers.CharField(source='category.name', read_only=True)class Meta:model = Productfields = ('id', 'name', 'description', 'price', 'category', 'category_name', 'image', 'stock', 'is_active', 'created_at')class OrderItemSerializer(serializers.ModelSerializer):product_name = serializers.CharField(source='product.name', read_only=True)class Meta:model = OrderItemfields = ('id', 'product', 'product_name', 'quantity', 'price')class OrderSerializer(serializers.ModelSerializer):items = OrderItemSerializer(many=True, read_only=True)user_info = UserSerializer(source='user', read_only=True)class Meta:model = Orderfields = ('id', 'user', 'user_info', 'total_amount', 'status', 'shipping_address', 'items', 'created_at', 'updated_at')

第四阶段:视图和API端点

4.1 创建视图(api/views.py)

from rest_framework import viewsets, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from django.contrib.auth.models import User
from .models import Category, Product, UserProfile, Order, OrderItem
from .serializers import (UserSerializer, UserProfileSerializer, CategorySerializer, ProductSerializer, OrderSerializer, OrderItemSerializer)class UserViewSet(viewsets.ModelViewSet):queryset = User.objects.all()serializer_class = UserSerializerpermission_classes = [permissions.IsAdminUser]  # 只有管理员可以管理用户class UserProfileViewSet(viewsets.ModelViewSet):queryset = UserProfile.objects.all()serializer_class = UserProfileSerializerdef get_queryset(self):# 用户只能访问自己的资料if self.request.user.is_staff:return UserProfile.objects.all()return UserProfile.objects.filter(user=self.request.user)class CategoryViewSet(viewsets.ModelViewSet):queryset = Category.objects.all()serializer_class = CategorySerializerpermission_classes = [permissions.IsAuthenticatedOrReadOnly]  # 读不需要认证class ProductViewSet(viewsets.ModelViewSet):queryset = Product.objects.filter(is_active=True)serializer_class = ProductSerializer@action(detail=False, methods=['get'])def by_category(self, request):category_id = request.query_params.get('category')products = Product.objects.filter(category_id=category_id, is_active=True)serializer = self.get_serializer(products, many=True)return Response(serializer.data)class OrderViewSet(viewsets.ModelViewSet):serializer_class = OrderSerializerdef get_queryset(self):# 用户只能查看自己的订单,管理员可以查看所有if self.request.user.is_staff:return Order.objects.all()return Order.objects.filter(user=self.request.user)def perform_create(self, serializer):# 自动设置当前用户为订单所有者serializer.save(user=self.request.user)class AuthViewSet(viewsets.ViewSet):"""认证相关接口"""@action(detail=False, methods=['post'], permission_classes=[permissions.AllowAny])def register(self, request):# 用户注册逻辑serializer = UserSerializer(data=request.data)if serializer.is_valid():user = User.objects.create_user(username=request.data['username'],email=request.data.get('email', ''),password=request.data['password'])# 创建用户资料UserProfile.objects.create(user=user)return Response({'message': '用户注册成功'}, status=status.HTTP_201_CREATED)return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

第五阶段:路由配置

5.1 配置URL路由(api/urls.py)

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from .views import (UserViewSet, UserProfileViewSet, CategoryViewSet, ProductViewSet, OrderViewSet, AuthViewSet)router = DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'profiles', UserProfileViewSet)
router.register(r'categories', CategoryViewSet)
router.register(r'products', ProductViewSet)
router.register(r'orders', OrderViewSet)
router.register(r'auth', AuthViewSet, basename='auth')urlpatterns = [path('', include(router.urls)),path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

5.2 主项目路由配置(backend/urls.py)

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import staticurlpatterns = [path('admin/', admin.site.urls),path('api/', include('api.urls')),  # API路由
]# 开发环境提供媒体文件服务
if settings.DEBUG:urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

第六阶段:安卓端接口调用示例

6.1 登录获取Token

// Kotlin 示例代码
interface ApiService {@POST("api/token/")suspend fun login(@Body request: LoginRequest): TokenResponse@POST("api/auth/register/")suspend fun register(@Body request: RegisterRequest): Response<MessageResponse>
}data class LoginRequest(val username: String, val password: String)
data class TokenResponse(val access: String, val refresh: String)
data class RegisterRequest(val username: String, val email: String, val password: String)
data class MessageResponse(val message: String)

6.2 获取商品列表

@GET("api/products/")
suspend fun getProducts(@Header("Authorization") token: String,@Query("page") page: Int = 1
): Response<ProductListResponse>@GET("api/products/by_category/")
suspend fun getProductsByCategory(@Header("Authorization") token: String,@Query("category") categoryId: Int
): Response<List<ProductResponse>>

6.3 创建订单

@POST("api/orders/")
suspend fun createOrder(@Header("Authorization") token: String,@Body request: CreateOrderRequest
): Response<OrderResponse>

第七阶段:生产环境部署配置

7.1 安全配置(settings.py)

# 生产环境设置
DEBUG = False# 允许的域名
ALLOWED_HOSTS = ['yourdomain.com', 'api.yourdomain.com']# CORS 白名单
CORS_ALLOWED_ORIGINS = ["https://yourapp.android.com","https://yourdomain.com",
]# 数据库配置
DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': 'mydatabase','USER': 'myuser','PASSWORD': 'mypassword','HOST': 'localhost','PORT': '5432',}
}# 静态文件和媒体文件配置
STATIC_URL = '/static/'
STATIC_ROOT = '/var/www/backend/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/var/www/backend/media/'

7.2 添加限流和缓存

REST_FRAMEWORK = {# ... 其他配置'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle','rest_framework.throttling.UserRateThrottle'],'DEFAULT_THROTTLE_RATES': {'anon': '100/day',  # 匿名用户100次/天'user': '1000/day'  # 认证用户1000次/天},'DEFAULT_CACHE_RESPONSE_TIMEOUT': 300  # 5分钟缓存
}

第八阶段:API文档和测试

8.1 安装DRF Spectacular用于API文档

pip install drf-spectacular

8.2 配置API文档

# settings.py
INSTALLED_APPS = [# ...'drf_spectacular',
]REST_FRAMEWORK = {# ...'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}SPECTACULAR_SETTINGS = {'TITLE': '安卓APP API','DESCRIPTION': '为安卓应用提供的RESTful API接口','VERSION': '1.0.0',
}

8.3 添加文档路由

# urls.py
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerViewurlpatterns = [# ...path('api/schema/', SpectacularAPIView.as_view(), name='schema'),path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),path('api/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]

完整的功能特性

✅ 用户系统: 注册、登录、JWT认证、用户资料管理
✅ 商品管理: 分类、商品列表、搜索、详情
✅ 订单系统: 创建订单、订单状态管理、历史订单
✅ 权限控制: 用户权限、管理员权限
✅ 文件上传: 用户头像、商品图片
✅ 分页和过滤: 大数据量分页显示
✅ API文档: 自动生成的交互式文档
✅ 安全机制: CORS、限流、SQL注入防护
✅ 错误处理: 统一的错误响应格式

这个完整的API后端可以为安卓应用提供所有必要的接口服务,具有良好的扩展性和安全性。


文章转载自:

http://p4S0aBjN.qxkjy.cn
http://a7tc0KfW.qxkjy.cn
http://0VpGAYQR.qxkjy.cn
http://oYiLdv2e.qxkjy.cn
http://1Ow1D59B.qxkjy.cn
http://U74M5pAE.qxkjy.cn
http://KttlY19t.qxkjy.cn
http://ZaCEFZ5M.qxkjy.cn
http://MY30J5Oc.qxkjy.cn
http://QMo5zLbu.qxkjy.cn
http://0qyc4DVe.qxkjy.cn
http://eslBQu8A.qxkjy.cn
http://pSidJvuN.qxkjy.cn
http://eGLvedNG.qxkjy.cn
http://lPPU7jFs.qxkjy.cn
http://BuIcXMWM.qxkjy.cn
http://PFn0RxV4.qxkjy.cn
http://3FuQkcQY.qxkjy.cn
http://LD05EEIO.qxkjy.cn
http://VvbKP6gx.qxkjy.cn
http://Ay4OQK5z.qxkjy.cn
http://JQJDSRtP.qxkjy.cn
http://HM4kWpsL.qxkjy.cn
http://PVFRqD7s.qxkjy.cn
http://zSPxbYQd.qxkjy.cn
http://PmjvyZ2E.qxkjy.cn
http://3K3w49B0.qxkjy.cn
http://eU7cg6Oa.qxkjy.cn
http://2dw4GYcQ.qxkjy.cn
http://ibMninN7.qxkjy.cn
http://www.dtcms.com/a/376665.html

相关文章:

  • neo4j数据库创建范例(SQL文)
  • [rStar] docs | 求解协调器
  • WPF迁移avalonia之触发器
  • 【WPF+Prism】日常开发问题总结
  • 差异基因分析实战:手把手教你用R语言找到关键基因
  • 金融数据库--3Baostock
  • 【ICLR 2023】可逆列网络(RevCol)
  • Java SE 与常用框架
  • Web安全基石:深入理解与防御越权问题
  • 手写MyBatis第58弹:如何优雅输出可执行的SQL语句--深入理解MyBatis日志机制:
  • 2025流量新逻辑:AI × IP × 联盟|创客匠人
  • UGUI源码剖析(15):Slider的运行时逻辑与编辑器实现
  • 第 16 篇:服务网格的未来 - Ambient Mesh, eBPF 与 Gateway API
  • 基于Matlab不同作战类型下兵力动力学模型的构建与稳定性分析
  • 基于AIS动态数据与AI结合得经纬度标示算法
  • 第5章 HTTPS与安全配置
  • ZYNQ PL端采集AD7606数据与ARM端QT显示实战指南
  • 头条号采集软件V12.2主要更新内容
  • 吱吱企业即时通讯平衡企业通讯安全与协作,提升企业办公效率
  • 中线安防保护器,也叫终端电气综合治理保护设备为现代生活筑起安全防线
  • 从零实现一个简化版string 类 —— 深入理解std::string的底层设计
  • 记一次Cloudflare五秒盾的研究
  • RDMA和RoCE有损无损
  • 大数据毕业设计选题推荐-基于大数据的护肤品店铺运营数据可视化分析系统-Hadoop-Spark-数据可视化-BigData
  • C#,RabbitMQ从入门到精通,.NET8.0(路由/分布式/主题/消费重复问题 /延迟队列和死信队列/消息持久化 )/RabbitMQ集群模式
  • 开源芯片革命的起源与未来
  • 开源的Web服务器管理平台Termix
  • Dify开源AI框架介绍
  • Git 技巧:用 --no-walk 参数 + 别名,精准显示指定提交记录
  • kafka3.8集群搭建