Django如何基于MySQL多表创建自定义ModelSerializer?
解决方案
方式一:模型关联+序列化器自定义字段(推荐)
这种方式贴合Django ORM设计,代码更易维护和扩展,是长期项目的最优选择。
1. 完善模型关联
适配现有MySQL表结构,在模型中建立多对多关联:
# map/api/models.py from django.db import models class RadarSites(models.Model): radar_id = models.IntegerField(primary_key=True) # 替换为你实际的雷达名称字段(比如site_name) name = models.CharField(max_length=255, db_column='site_name') class Meta: db_table = 'radar_sites' class UserpieUsers(models.Model): user_id = models.IntegerField(primary_key=True) last_name = models.CharField(max_length=255) first_name = models.CharField(max_length=255) last_radar = models.CharField(max_length=255) # 通过中间表建立多对多关联 radars = models.ManyToManyField( RadarSites, through='UserpieUsers2Radars', through_fields=('user_id', 'radar_id'), related_name='related_users' ) class Meta: db_table = 'userpie_users' class UserpieUsers2Radars(models.Model): id = models.IntegerField(primary_key=True) user_id = models.ForeignKey(UserpieUsers, on_delete=models.CASCADE, db_column='user_id') radar_id = models.ForeignKey(RadarSites, on_delete=models.CASCADE, db_column='radar_id') class Meta: db_table = 'userpie_users2radars'
2. 修改序列化器添加自定义字段
用SerializerMethodField生成需求中的二维数组格式:
# map/api/serializers.py from rest_framework import serializers from .models import UserpieUsers class UserpieUserstSerializer(serializers.ModelSerializer): radars = serializers.SerializerMethodField() class Meta: model = UserpieUsers fields = ['user_id', 'last_name', 'first_name', 'last_radar', 'radars'] def get_radars(self, obj): # 直接通过ORM关联获取雷达ID和名称,自动序列化为二维数组 return obj.radars.values_list('radar_id', 'name')
3. 视图无需改动
原视图代码保持不变,序列化器会自动将radars字段加入响应结果。
方式二:手动查询追加数据(快速实现)
若不想修改模型结构,可直接在视图中手动查询关联数据并追加到响应:
# map/api/views.py from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from .models import UserpieUsers, UserpieUsers2Radars, RadarSites from .serializers import UserpieUserstSerializer @api_view(('GET',)) def api_user_radars(request, user_id): try: user_object = UserpieUsers.objects.get(user_id=user_id) except UserpieUsers.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == "GET": serializer = UserpieUserstSerializer(user_object) # 查询用户关联的雷达ID列表 related_radar_ids = UserpieUsers2Radars.objects.filter(user_id=user_id).values_list('radar_id', flat=True) # 批量获取对应的雷达ID和名称 radar_data = RadarSites.objects.filter(radar_id__in=related_radar_ids).values_list('radar_id', 'name') # 将雷达数据追加到序列化结果中 response_data = serializer.data response_data['radars'] = list(radar_data) return Response(response_data)
注意事项
- 请根据实际数据库字段调整代码中的字段名(比如雷达名称可能不是
name,而是site_name等); - 方式一适合长期维护的项目,ORM关联能减少重复代码;方式二适合临时快速需求。
内容的提问来源于stack exchange,提问作者Bryant Irawan
相关产品推荐
相关产品推荐

