Как объединить два стола без использования внешнего ключа с указанием uid - PullRequest
1 голос
/ 16 января 2020

Я новичок в DRF. Я видел несколько решений, но в моем случае это не сработало: у меня 2 модели, у которых одинаковый ID пользователя. Я хочу объединить обе таблицы, я пробовал, но это не сработало. Мой модальный класс:

class UserGPSFeed(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete = models.CASCADE
    )
    device = models.ForeignKey(
        'UserSensorDevice',
        on_delete = models.CASCADE,
        null=True
    )
    hardware_serial = models.CharField(max_length=255, null=True)
    fixok = models.BooleanField()

class UserSensorDevice(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    sensor_type = models.ForeignKey(
        'SensorDevice',
        on_delete=models.CASCADE
    )
    pseudonym = models.CharField(max_length=255)
    sensor_code = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)

Мой класс сериализатора

class UserGPSFeedSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserGPSFeed
        fields = '__all__'
        read_only_fields = ['id','created_at',]

class UserSensorDeviceWithParamSerializer(serializers.ModelSerializer):
    user = UserGPSFeedSerializer(many=False,read_only=True)
    class Meta:
        model = models.UserSensorDevice
        fields = '__all__'
        read_only_fields = ['id','created_at']

Views.py

class UserSensorDeviceParamListView(generics.ListAPIView):
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = serializers.UserSensorDeviceWithParamSerializer
    queryset = models.UserSensorDevice.objects.filter(sensor_type=2)

    def get_queryset(self):
        return self.queryset.filter(user=self.request.user)

Я хочу получить все пользовательские сенсорные устройства с параметром. так как оба имеют одинаковый внешний ключ. Так есть ли способ связать такого рода ситуации. Любая помощь будет высоко оценена. Спасибо!

1 Ответ

1 голос
/ 16 января 2020

Я не совсем уверен в вашей цели, но если вы просто хотите включить некоторые данные, основанные на том, что у вас есть в вашем текущем сериализаторе, вы можете попробовать это

class UserSensorDeviceWithParamSerializer(serializers.ModelSerializer):
    user_gps = serializers.SerializerMethodField()

    def get_user_gps(self, obj):
        # you can do this
        return UserGPSFeed.objects.filter(user_id=obj.user_id)
        # OR if you prefer
        return UserGPSFeed.objects.filter(user=obj.user)
        # both are the same but using user_id may give a slightly faster performance

    class Meta:
        model = models.UserSensorDevice
        fields = '__all__'
        read_only_fields = ['id','created_at']

Обратите внимание, что user_id имя столбца, созданного в вашей модели при указании внешнего ключа, поскольку он содержит идентификатор для записанного, он указывает на

Обновление : в отношении ошибки Object of type UserGPSFeed is not JSON serializable это означает, что django не удалось проанализировать результат до json автоматически, потому что это не экземпляр модели, а набор запросов - извините, я забыл обработать это - поэтому для этого нам нужно использовать сериализатор, чтобы сериализовать каждый объект в возвращенном наборе запросов.

К счастью, вы уже создали этот сериализатор, поэтому нам нужно только передать ему возвращенный набор запросов, поэтому мы обновляем get_user_gps(), чтобы он был таким,

def get_user_gps(self, obj):
    user_gps_queryset = UserGPSFeed.objects.filter(user_id=obj.user_id)
    user_gps_serializer = UserGPSFeedSerializer(user_gps_queryset, many=True)
    return user_gps_serializer.data

Первый пример все еще действителен, конечно если он вернет один объект

...