Получить данные в многоуровневом вложенном сериализаторе с помощью Django Rest

#django-rest-framework

#django-rest-framework

Вопрос:

Необходимо сериализовать три модели, вложенные на трех уровнях. Есть области, назначенные пользователям, и они содержат точки. Пользователи содержат несколько областей. С областями связано несколько точек. Пользователи связывают области, используя отношение «многие ко многим». Области связываются с точкой, используя Foreign в точках. Пользователи могут быть назначены нескольким областям. Области могут иметь несколько точек.

Модель профиля пользователя

 class UserProfile(AbstractBaseUser,PermissionsMixin):
      phone_number= PhoneNumberField( unique=True)
      name=models.CharField(max_length=255)
      organisation=models.CharField(max_length=255)
      is_active=models.BooleanField(default=True)
      is_staff=models.BooleanField(default=False)
      added_by=models.ForeignKey(settings.AUTH_USER_MODEL,default=1)  
      group = models.ForeignKey('auth.Group', null=True)
      areas=models.ManyToManyField('area.Area',blank=True)
      objects=UserProfileManager()
  

Модель областей

 from django.db import models
from django.conf import settings

 # Create your models here.
class Area(models.Model):
      areaName =models.TextField()
      timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
      updated = models.DateTimeField(auto_now=True, auto_now_add=False)
      user = models.ForeignKey(settings.AUTH_USER_MODEL )
      def __str__(self):
         return self.areaName 
  

Точечная модель

 from django.db import models

from django.conf import settings

# Create your models here.
class Point(models.Model):
    name =models.TextField()
    area = models.ForeignKey('area.Area', on_delete=models.CASCADE)
    latitude=models.CharField(max_length=200)
    longitude=models.CharField(max_length=200)
    timestamp=models.DateTimeField(auto_now=False,auto_now_add=True)
    updated=models.DateTimeField(auto_now=True,auto_now_add=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL )
    def __str__(self):
        return self.name 
  

Я хочу получить результат, подобный следующему:

    {
        "id": 3,
        "phone_number": " 919999999999",
        "name": "Ak",
        "organisation": "sp",
        "group": 1,
        "areas": [
            {
                "id": 1,
                "areaName": "Area 51",
                "user": 1
                points:[{
                    
                }]
            },
            {
                "id": 2,
                "areaName": "Rrea 343",
                "user": 1
                point:[{}]
            }
        ]
    },
    {
        "id": 4,
        "phone_number": " 918888888888",
        "name": "Chitra Sahu",
        "organisation": "sd",
        "group": 2,
        "areas": [
            {
                "id": 1,
                "areaName": "Area 51",
                "user": 1
                point:[{
                     
                    latitude:'23.2323',
                  longitude:'23.2323'
                },
                {
                   
                    latitude:'21.1223',
                  longitude:'32.34345'
                }
                ]
            },
            {
                "id": 2,
                "areaName": "Rrea 343",
                "user": 1
                point:[{
                     
                    latitude:'23.2323',
                  longitude:'23.2323'
                },
                {
                   
                    latitude:'21.1223',
                  longitude:'32.34345'
                }]
            }
        ]
    },  

До сих пор я пробовал следующее

 class AreasSerializer(serializers.ModelSerializer):
class Meta:
	model=Area
	fields=('id','areaName','user')
class AreasUserSerializer(serializers.ModelSerializer):
	areas = AreasSerializer(many=True, read_only=True)

	class Meta:
		model = UserProfile
		fields = ('id','phone_number','name','organisation','group','areas')
class AreasUserPointSerializer(serializers.ModelSerializer):
	areasUsers=AreasUserSerializer()
	class Meta: 
		model=Point
	fields =('id','areasUsers' )  

Число просмотров

 '''Fetch list all question '''
class AreasPointsUsersListApiView(ListAPIView):
	
	
	serializer_class=serializers.AreasUserPointSerializer
	def get_queryset(self):
		queryset=UserProfile.objects.all()
		user=self.request.query_params.get('user_id',None)
		if user is not None:
			queryset = queryset.filter(id=user)
		#if areas is not None:
		#	queryset = queryset.filter(areas=areas)
		return queryset  

.py

Этот код работает неправильно. Мне нужно сериализовать его так, чтобы пользователи состояли из областей, основанных на отношениях «Многие ко многим». Эти области связаны с point с помощью внешнего ключа в Point.

Редактировать

Редактировать: сериализатор областей

Комментарии:

1. можете ли вы также добавить представления?

2. @JPG Я также добавил представление.

3. Похоже, что сериализатор верхнего уровня — это AreasUserLocationSerializer тот, который вы не включили. Не возражаете добавить это? Вы не на правильном пути, определяя несколько классов сериализатора… это будет просто вопрос правильного определения вложенности и полей.

4. @DwightGunning Это то же самое AreasUserPointSerializer . Изменил его

5. Хорошо, поэтому AreasSerializer не показано. Это затрудняет понимание того, что происходит на самом деле. Не могли бы вы, пожалуйста, опубликовать все ваши классы сериализатора, а также добавить пример того, как выглядит ответ в настоящее время?

Ответ №1:

Я решил это с помощью LocationSerializer, который вызывается AreasSerializer. Я делюсь фрагментом кода. Это было довольно просто.

  
class PointSerializer(serializers.ModelSerializer):
	 class Meta:
	 	model = Point
	 	fields=('id','latitude','longitude')
class AreasLocationSerializer(serializers.ModelSerializer):
	points = PointSerializer(many =True, read_only=True)
	class Meta:
		model=Area
		fields=('id','areaName','points','user')

 
class AreasUserLocationSerializer(serializers.ModelSerializer):
	areas =AreasLocationSerializer(many=True, read_only=True)
	class Meta: 
		model=UserProfile
		fields =('id','phone_number','name','areas')  

Комментарии:

1. Рекомендуем отметить ваш ответ как правильный, поскольку он решает проблему.

2. @DwightGunning Осталось два дня

3. @AkhilSahu, у меня похожая проблема. Как и у вас Point , у меня есть вложенные данные post. Но это не другая модель. В методе serializers create я хочу получить эти данные, такие как validated_data.pop('point') или validated_data.get('point') . Но я не могу этого сделать, потому что он вложенный. Есть ли какой-нибудь способ взломать это?

4. Получите родительские данные, и вы получите вложенные в них данные в том же процессе. s = validated_data.pop(‘точка’) s[‘вложенный’][‘данные’]