Home > Blockchain >  How to get the many to one relatiodata on DRF
How to get the many to one relatiodata on DRF

Time:03-28

How can I get the information which has a relationship with another modal class For eg.

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

And I have another modal class:

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)

When I will call UserSensorSerializer then if replacement is available then I need to get that information as well. I am not able to figure it out how can I get that

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

Any suggestion will be of great help.

CodePudding user response:

You can help out by adding related_name arguments

user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='userDetails'
    )

and/or add depth to serializer class

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

CodePudding user response:

The UserSensorDevice and ReplacedSensorDevice models are quite similar, I think you must define one model (SensorDevice) with one field that shows that the object is a user device or replaced device, like below :

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

advantage of this strategy is, you can get all of the user sensor devices and their replacement by one queryset and serialize them by one serializer class.

I mean you can create a serializer class like this:

class SensorDeviceSerializer(serializers.ModelSerializer):    
    class Meta:
        model = sensorModels.SensorDevice
        fields = '__all__'
        read_only_fields = ['id','created_at']

and then get your needed objects in view:

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

also if you want to make difference between users and replace sensor devices, you can add params to your queryset in your view.

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
  • Related