[Answered ]-Django: How to create custom ModelSerializer from multiple models/tables in mySQL database?

0πŸ‘

βœ…

To serialize relied model you basically need to make serializer for relied model and add it as field to your "main" serializer:

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']

This will give you output like that:

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

If getting radars as list of pairs, instead of dict is necessary for you you can do something like:

#in models.py

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

and in serializers:

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']

1πŸ‘

I just wanted to share a more optimized solution based on the one that worked for you:

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

        radar_ids = list(UserpieUsers2Radars.objects.filter(
            user_id=user_id).values_list('radar_id', flat=True))
        # radar_ids = [radar.radar_id for radar in radars] you avoid this N+1 queries

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

        radar_data = [[i['id'], i['name']] for i in radar_serializer.data]

        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)
πŸ‘€allexiusw

0πŸ‘

Found a solution!

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)

urls.py

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

]

πŸ‘€Bryant Irawan

Leave a comment