#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[‘вложенный’][‘данные’]