Django:如何从mySQL数据库中的多个模型/表创建自定义ModelSerializer?

r1wp621o  于 2023-08-08  发布在  Go
关注(0)|答案(2)|浏览(104)

我正在使用一个已经存在的mySQL数据库进行Django项目。我很快了解到,mySQL缺乏postgresSQL数据库中的显式关系,在postgresSQL数据库中,您可以建立一对一,一对多,多对多的关系。相反,您通常需要仅为关系创建一个完整的其他表。
目前,我有三个表:userpie_users、radar_sites和userpie_users2radars(描述关系的表)。

表:userpie_usersx1c 0d1x
表:radar_sites

表:userpie_users2radars

为了澄清这一点,让我们检查第一行userpie_users2radars:id:2,user_id:78、radar_id:17
id:2可以忽略,但此行指定来自userpie_users的user_id(78)附加到来自radar_sites的radar_id(17)。下一行显示同一个用户也连接到radar_id(4)。
对于我的API“GET”端点(http://127.0.0.1:8000/api/map/user_id),我希望我的最终JSON主体响应是这样的:

{
    "user_id":"123",
    "last_name":"smith",
    "first_name":"john",
    "last_radar":"28",
    "radars":[["19","Coal Point Reserve UCSB"],["39","Harvey"],["33","Hawaii"]]
}

字符串
前四个字段位于userpie_users表中,因此可以使用ModelSerializer轻松序列化。“last_radar”在截图中被切断,但它在那里。
然而,“radars”是一个数组,我需要从url参数中获取user_id,查看userpie_users2radars中的每一行,如果user_id匹配,则获取radar_id。然后,我将有一个radar_id数组,我将需要循环通过radar_sites表并获取radar_site的名称(例如。哈维,夏威夷)。将radar_id和名称组合在一起,并将其放入数组中。

map/API/views.py

@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)
        return Response(serializer.data)

map/API/serializers.py:

class UserpieUserstSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserpieUsers
        fields = ['user_id', 'last_name', 'first_name', 'last_radar']

map/API/urls.py:

urlpatterns = [
    path('<user_id>/', api_user_radars, name="userpie_users")
]


创建雷达阵列并将其合并到JSON主体中的最佳方法是什么?

ix0qys7i

ix0qys7i1#

要序列化依赖模型,你基本上需要为依赖模型制作序列化器,并将其作为字段添加到你的“主”序列化器中:

class RadarSerializer(serializers.ModelSerializer):
     class Meta:
            model = YourRadarModel
            fields = ["id", "name"]

class UserpieUserstSerializer(serializers.ModelSerializer):

    #name of this field must be same as name of ManyToMany field  or value of "related_name" in models.py, I called it radars
    radars = RadarSerializer(many=True, read_only=True) 

    class Meta:
        model = UserpieUsers
        fields = ['user_id', 'last_name', 'first_name', 'last_radar', 'radars']

字符串
这将给予你这样的输出:

{
    "user_id":"123",
    "last_name":"smith",
    "first_name":"john",
    "last_radar":"28",
    "radars":[
              {"id": "19",
               "name": "Coal Point Reserve UCSB"},
              {"id": "39",
               "name": "Harvey"},
               ....
}


如果将雷达作为对的列表,而不是dict对你来说是必要的,你可以这样做:

#in models.py

class YourRadarModel(models.Model):
   #...
   #some fields
   @property
   def id_and_name_pair(self):
        return [self.id, self.name]


在序列化器中:

from rest_framework.serializers  RelatedField

class RadarField(serializers.RelatedField):
    def to_representation(self, value):
        return value.id_and_name_pair

class UserpieUserstSerializer(serializers.ModelSerializer):

        radars = RadarField(many=True, read_only=True) 

        class Meta:
            model = UserpieUsers
            fields = ['user_id', 'last_name', 'first_name', 'last_radar', 'radars']

fzwojiic

fzwojiic2#

找到解决办法了!

serializers.py

class UserpieUsersSerializer(serializers.ModelSerializer):
class Meta:
    model = UserpieUsers
    fields = ['user_id', 'last_name', 'first_name', 'last_radar']

class RadarSitesSerializer(serializers.ModelSerializer):
    class Meta:
        model = RadarSites
        fields = ['id', 'name', 'status']

字符串

views.py

@api_view(('GET',))
def get_user_radars(request, user_id):
    try:
        user = UserpieUsers.objects.get(user_id=user_id)
        user_serializer = UserpieUsersSerializer(user)

        radars = UserpieUsers2Radars.objects.filter(user_id=user_id)
        radar_ids = [radar.radar_id for radar in radars]

        radar_sites = RadarSites.objects.filter(id__in=radar_ids)  # Use "id" to filter radar_sites
        radar_serializer = RadarSitesSerializer(radar_sites, many=True)

        radar_data = []  # Collect radar data as a list of [id, name] lists
        for radar in radar_serializer.data:
            radar_data.append([radar['id'], radar['name']])

        response_data = {
            'user_id': user_serializer.data['user_id'],
            'last_name': user_serializer.data['last_name'],
            'first_name': user_serializer.data['first_name'],
            'last_radar': user_serializer.data['last_radar'],
            'radars': radar_data,
        }
        return Response(response_data)
    except UserpieUsers.DoesNotExist:
        return Response({'message': 'User not found'}, status=404)

url.py

urlpatterns = [
path('user/<user_id>/', get_user_radars, name="userpie_users_with_radar")


]

相关问题