Как получить реляционные данные "многие к одному" на DRF
Как я могу получить информацию, которая имеет отношение к другому модальному классу Например,
class UserSensorDevice(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
sensor_type = models.ForeignKey(
'core.Component',
on_delete=models.CASCADE
)
sensor_code = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.pseudonym
У меня есть другой модальный класс:
class ReplacedSensorDevice(models.Model):
sensor_type = models.ForeignKey(
'core.Component',
on_delete=models.CASCADE
)
replaced_for = models.ForeignKey(
'UserSensorDevice',
on_delete=models.CASCADE,
null=True
)
sensor_code = models.CharField(max_length=255, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Когда я вызываю UserSensorSerializer, то если замена доступна, то мне нужно получить и эту информацию. Я не могу понять, как я могу получить эту информацию
views.py
class UsersSensorDeviceView(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticated, jwtPermissions.IsOwner,)
queryset = sensorModels.UserSensorDevice.objects.all()
pagination_class = pagination.PostLimitOffsetPagination
filter_backends = (DjangoFilterBackend,OrderingFilter,SearchFilter)
filter_fields = ('user','id','sensor_type',)
serializer_class = serializers.UserSensorDeviceSerializer
serializers.py
class UserSensorDeviceSerializer(serializers.ModelSerializer):
sensor_name = serializers.CharField(source='sensor_type.comp_code', read_only=True)
class Meta:
model = sensorModels.UserSensorDevice
fields = '__all__'
read_only_fields = ['id','created_at']
Любое предложение будет очень полезным.
Вы можете помочь, добавив аргументы related_name
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='userDetails'
)
и/или добавить глубину в класс сериализатора
class UserSensorDeviceSerializer(serializers.ModelSerializer):
sensor_name = serializers.CharField(source='sensor_type.comp_code', read_only=True)
class Meta:
model = sensorModels.UserSensorDevice
fields = '__all__'
read_only_fields = ['id','created_at']
depth = 1
Модели UserSensorDevice и ReplacedSensorDevice довольно похожи, я думаю, что вы должны определить одну модель (SensorDevice) с одним полем, которое показывает, что объект является устройством пользователя или замененным устройством, как показано ниже :
class SensorDevice(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
sensor_type = models.ForeignKey(
'core.Component',
on_delete=models.CASCADE
)
sensor_code = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
is_user_sensor_device = models.BooleanField(default=false)
def __str__(self):
return self.pseudonym
Преимуществом этой стратегии является то, что вы можете получить все пользовательские сенсорные устройства и их замены одним набором запросов и сериализовать их одним классом сериализатора.
Я имею в виду, что вы можете создать класс сериализатора следующим образом:
class SensorDeviceSerializer(serializers.ModelSerializer):
class Meta:
model = sensorModels.SensorDevice
fields = '__all__'
read_only_fields = ['id','created_at']
и затем получить необходимые объекты в представлении:
class SensorDeviceView(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticated, jwtPermissions.IsOwner,)
queryset = sensorModels.SensorDevice.objects.all()
pagination_class = pagination.PostLimitOffsetPagination
filter_backends = (DjangoFilterBackend,OrderingFilter,SearchFilter)
filter_fields = ('user','id','sensor_type',)
serializer_class = serializers.SensorDeviceSerializer
Кроме того, если вы хотите сделать различие между пользователями и заменить сенсорные устройства, вы можете добавить параметры в ваш набор запросов в представлении.
class UserSensorDeviceView(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticated, jwtPermissions.IsOwner,)
queryset = sensorModels.SensorDevice.objects.filter(is_user_sensor_device=True)
pagination_class = pagination.PostLimitOffsetPagination
filter_backends = (DjangoFilterBackend,OrderingFilter,SearchFilter)
filter_fields = ('user','id','sensor_type',)
serializer_class = serializers.SensorDeviceSerializer