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后端可以为安卓应用提供所有必要的接口服务,具有良好的扩展性和安全性。